Compare commits
7
Commits
master
...
commander-auth
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94eb510d76 | ||
|
|
0f3ba0e890 | ||
|
|
513ecfefab | ||
|
|
ff4f3bbc1b | ||
|
|
f2634dcbd5 | ||
|
|
0b2d3f19c0 | ||
|
|
f41f17594f |
+130
-16
@@ -54,13 +54,36 @@ var dbpool = new Pool({
|
||||
})
|
||||
|
||||
|
||||
var projectPool;
|
||||
if (config.vncproject) {
|
||||
projectPool = new Pool({
|
||||
database: config.vncproject.name,
|
||||
user: config.vncproject.user,
|
||||
password: config.vncproject.pass,
|
||||
host: config.vncproject.host,
|
||||
port: config.vncproject.port,
|
||||
ssl: true,
|
||||
max: 20, // set pool max size to 20
|
||||
min: 4, // set min pool size to 4
|
||||
idleTimeoutMillis: config.database.idleTimeoutMillis, // close idle clients after 1 second
|
||||
connectionTimeoutMillis: config.database.connectionTimeoutMillis, // return an error after 1 second if connection could not be established
|
||||
})
|
||||
}
|
||||
|
||||
app.use(bodyParser.json()); // for parsing application/json
|
||||
app.use(logger('dev'));
|
||||
|
||||
function IsValidLDAPUser(username) {
|
||||
return new Promise( function (resolve, reject) {
|
||||
console.log("[IsValidLDAPUser start] username: ", username);
|
||||
var uid = username.split("@")[0];
|
||||
var domain = username.split("@")[1];
|
||||
var domain = config.domain;
|
||||
var email = username;
|
||||
if (username.indexOf("@") > -1) {
|
||||
domain = username.split("@")[1];
|
||||
} else {
|
||||
email = username + "@" + domain;
|
||||
}
|
||||
var dcstring = "ou=people,dc=";
|
||||
if (domain.indexOf(".") > -1 ){
|
||||
var dcstrings = domain.split(".");
|
||||
@@ -68,23 +91,26 @@ function IsValidLDAPUser(username) {
|
||||
dcstring += dcstrings.join(",dc=");
|
||||
}
|
||||
}
|
||||
console.log("uid: ", uid);
|
||||
console.log("domain: ", domain);
|
||||
console.log("dc: ", dcstring);
|
||||
var search_options = { scope : 'sub' };
|
||||
var _filter = '(&(objectClass=inetOrgPerson)';
|
||||
if (config.ldap.ldapType === 'zimbra') {
|
||||
_filter += '(!(zimbraIsSystemResource=TRUE))(!(zimbraIsSystemAccount=TRUE))';
|
||||
_filter += '(!(objectClass=zimbraDistributionList))(!(objectClass=zimbraCalendarResource))';
|
||||
_filter += '(&(zimbraAccountStatus=active))(&(zimbraMailStatus=enabled))';
|
||||
_filter += '(|(uid=' + uid + ')(mail=' + username + ')))';
|
||||
_filter += '(|(uid=' + uid + ')(mail=' + email + ')))';
|
||||
search_options.filter = _filter;
|
||||
// search_options.attributes = ['uid', 'mail', 'givenName', 'sn', 'displayName', 'zimbraAccountStatus'];
|
||||
search_options.attributes = ['uid', 'mail', 'zimbraAccountStatus'];
|
||||
search_options.attributes = ['uid', 'mail', 'zimbraAccountStatus', 'givenName', 'sn', 'displayName', 'title', 'telephoneNumber', 'l', 'street', 'postalCode', 'co'];
|
||||
} else if (config.ldap.ldapType === 'MS-AD') {
|
||||
_filter += '(|(sAMAccountName=' + uid + ')(mail=' + username + ')))';
|
||||
search_options.filter = _filter;
|
||||
search_options.attributes = ['sAMAccountName', 'mail', 'givenName', 's', 'displayName' ];
|
||||
search_options.attributes = ['sAMAccountName', 'mail', 'givenName', 'sn', 'displayName' ];
|
||||
} else {
|
||||
console.error(moment().format("LTS") + " [profile ldap] unsupported config.ldap.ldapType : '"+config.ldap.ldapType+"'");
|
||||
resolve(false);
|
||||
resolve(null);
|
||||
}
|
||||
console.log(moment().format("LTS") + ' ldap filter: ', _filter);
|
||||
ldap.bind(
|
||||
@@ -93,14 +119,14 @@ function IsValidLDAPUser(username) {
|
||||
err => {
|
||||
if (err) {
|
||||
console.error(moment().format("LTS") + " [profile ldap.bind]", err);
|
||||
resolve(false);
|
||||
resolve(null);
|
||||
} else {
|
||||
var resultEntries = [];
|
||||
console.log(moment().format("LTS") + ' [profile ldap.search] dcstring:', dcstring);
|
||||
ldap.search(dcstring, search_options, (error, searchResult) => {
|
||||
if (error) {
|
||||
console.error(moment().format("LTS") + " [profile ldap.search error] ", error);
|
||||
resolve(false);
|
||||
resolve(null);
|
||||
}
|
||||
searchResult.on('searchEntry' , e => {
|
||||
var resultEntry = {};
|
||||
@@ -117,13 +143,14 @@ function IsValidLDAPUser(username) {
|
||||
{
|
||||
console.log('[search-ldap.end] status=' + status.status + " ("+status.errorMessage+")", resultEntries.length+ " entries");
|
||||
if (resultEntries.length === 1) {
|
||||
console.log(moment().format("LTS") + " [valid LDAP user] resultEntries: ", resultEntries);
|
||||
console.log(moment().format("LTS") + " [valid LDAP user] ", username);
|
||||
ldap.unbind();
|
||||
resolve(true);
|
||||
resolve(resultEntries[0]);
|
||||
} else {
|
||||
console.log(moment().format("LTS") + " [no valid LDAP user] - sending 401");
|
||||
ldap.unbind();
|
||||
resolve(false);
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -154,6 +181,7 @@ function IsValidLDAPAuth(username, password) {
|
||||
console.error(moment().format("LTS") + " [profile ldap] unsupported config.ldap.ldapType : '"+config.ldap.ldapType+"'");
|
||||
resolve(false);
|
||||
}
|
||||
console.log("LDAP Auth - UID DN: ", uiddn);
|
||||
ldap.bind( uiddn, password,
|
||||
err => {
|
||||
if (err) {
|
||||
@@ -169,18 +197,53 @@ function IsValidLDAPAuth(username, password) {
|
||||
});
|
||||
}
|
||||
|
||||
function getProjectApiKey(username) {
|
||||
return new Promise( function (resolve, reject) {
|
||||
var pqueryparams = [];
|
||||
pqueryparams[0] = username;
|
||||
pqueryparams[1] = "api";
|
||||
pquery = "select tokens.value AS RedmineAPIKey from tokens where tokens.action=$2 and tokens.user_id in ";
|
||||
pquery += "(select id from users where users.status=1 and id in (select user_id from email_addresses where address=$1))"
|
||||
projectPool.query(pquery, pqueryparams, function (perr, pres) {
|
||||
if (perr != null) {
|
||||
console.log("db connection error: ", perr);
|
||||
resolve(null);
|
||||
} else {
|
||||
if (pres.rowCount > 0) {
|
||||
console.log("pres: ", pres.rows);
|
||||
resolve(pres.rows[0].redmineapikey);
|
||||
} else {
|
||||
resolve(null);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function IsValidRedmineUser(username) {
|
||||
return new Promise( function (resolve, reject) {
|
||||
var uid = username.split("@")[0];
|
||||
var query = ""
|
||||
var queryparams = [];
|
||||
queryparams[0] = uid;
|
||||
var query = "SELECT DISTINCT ON (uid) users.login AS uid, users.firstname AS givenName, users.lastname AS sn FROM users WHERE users.status=1 AND users.login=$1";
|
||||
queryparams[1] = "api";
|
||||
var query = "SELECT DISTINCT ON (uid) users.login AS uid, users.firstname AS givenName, users.lastname AS sn, ";
|
||||
query += "email_addresses.address as email, tokens.value AS RedmineAPIKey FROM users, tokens, email_addresses ";
|
||||
query += "WHERE users.status=1 AND users.login=$1 and tokens.action=$2 and tokens.user_id=users.id and email_addresses.user_id=users.id";
|
||||
|
||||
// var query = "select SELECT DISTINCT ON (uid) users.login AS uid, users.firstname AS givenName, users.lastname AS sn, users.login||\'@talk.vnc.de\' AS mail FROM users WHERE users.status=1 AND users.login=$1 AND substring(users.hashed_password, 0, length(users.hashed_password)+1) = encode(digest(users.salt||encode(digest(:password, \'sha1\'), \'hex\'), \'sha1\'), \'hex\')";
|
||||
dbpool.query(query, queryparams, function (derr, dres) {
|
||||
if (derr == null) {
|
||||
if (dres.rowCount > 0) {
|
||||
resolve(true);
|
||||
var redmineUser = {
|
||||
id: dres.rows[0].uid,
|
||||
firstname: dres.rows[0].givenname,
|
||||
lastname: dres.rows[0].sn,
|
||||
email: dres.rows[0].email,
|
||||
displayName: dres.rows[0].givenname + " " + dres.rows[0].sn,
|
||||
redmineapikey: dres.rows[0].redmineapikey
|
||||
}
|
||||
resolve(redmineUser);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
@@ -279,6 +342,16 @@ function IsValidJWT(username,password) {
|
||||
}
|
||||
}
|
||||
|
||||
function getFirstElement(elements) {
|
||||
var result;
|
||||
if (typeof(elements) == "string"){
|
||||
result = elements;
|
||||
} else if (typeof(elements) == "object") {
|
||||
result = elements[0];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
app.get('/', async function (req, res) {
|
||||
if (req.headers.authorization && req.headers.authorization.startsWith("Basic")) {
|
||||
try {
|
||||
@@ -294,7 +367,13 @@ app.get('/', async function (req, res) {
|
||||
}
|
||||
}
|
||||
if (config.useRedmineAuth) {
|
||||
let validRedmineUser = await IsValidRedmineUser(username);
|
||||
let validRedmineUser = false;
|
||||
var finalProfile = {};
|
||||
let userProfile = await IsValidRedmineUser(username);
|
||||
|
||||
if (userProfile) {
|
||||
validRedmineUser = true;
|
||||
}
|
||||
console.log(moment().format("LTS") + ' username ' + username +' - IsValidRedmineUser: ', validRedmineUser);
|
||||
console.log(moment().format("LTS") + ' username ' + username +' - password: ', password);
|
||||
console.log(moment().format("LTS") + ' username ' + username +' - indesxforOldToken: ', password.indexOf("-"));
|
||||
@@ -304,7 +383,7 @@ app.get('/', async function (req, res) {
|
||||
console.log("IsValidOldSecret: ", IsValidOldSecret(username, password));
|
||||
console.log("IsValidJWT: ", IsValidJWT(username, password));
|
||||
if (validRedmineUser && (validRedmineAuth || IsValidOldSecret(username, password) || IsValidJWT(username, password))) {
|
||||
res.status(200).json(null);
|
||||
res.status(200).json(userProfile);
|
||||
} else {
|
||||
res.status(401).json(null);
|
||||
}
|
||||
@@ -321,15 +400,50 @@ app.get('/', async function (req, res) {
|
||||
res.status(401).json(null);
|
||||
}
|
||||
} else {
|
||||
let validLdapUser = await IsValidLDAPUser(username);
|
||||
var finalProfile = {};
|
||||
let userProfile = await IsValidLDAPUser(username);
|
||||
let projectApiKey = await getProjectApiKey(username);
|
||||
let validLdapUser = false;
|
||||
let userLdapName = username;
|
||||
console.log("got profile: ", userProfile);
|
||||
if (userProfile) {
|
||||
validLdapUser = true;
|
||||
}
|
||||
if (userProfile.uid && (userProfile.uid != null)) {
|
||||
finalProfile["id"] = getFirstElement(userProfile.uid);
|
||||
}
|
||||
if (userProfile.givenName && (userProfile.givenName != null)) {
|
||||
finalProfile["firstname"] = getFirstElement(userProfile.uid);
|
||||
}
|
||||
if (userProfile.sn && (userProfile.sn != null)) {
|
||||
finalProfile["lastname"] = getFirstElement(userProfile.sn);
|
||||
}
|
||||
if (userProfile.email && (userProfile.email != null)) {
|
||||
finalProfile["email"] = getFirstElement(userProfile.email);
|
||||
userLdapName = getFirstElement(userProfile.email);
|
||||
console.log("using for LDAP: ", userLdapName);
|
||||
}
|
||||
if (userProfile.mail && (userProfile.mail != null)) {
|
||||
finalProfile["email"] = getFirstElement(userProfile.email);
|
||||
userLdapName = getFirstElement(userProfile.mail);
|
||||
console.log("using for LDAP: ", userLdapName);
|
||||
}
|
||||
if (userProfile.displayName && (userProfile.displayName != null)) {
|
||||
finalProfile["displayName"] = getFirstElement(userProfile.displayName);
|
||||
}
|
||||
if (projectApiKey && (projectApiKey != null)) {
|
||||
finalProfile["RedmineApiKey"] = projectApiKey;
|
||||
}
|
||||
console.log(moment().format("LTS") + ' username ' + username +' - validInLDAP: ', validLdapUser);
|
||||
console.log(moment().format("LTS") + ' username ' + username +' - password: ', password);
|
||||
console.log(moment().format("LTS") + ' username ' + username +' - indesxforOldToken: ', password.indexOf("-"));
|
||||
if (validLdapUser === true) {
|
||||
let validLdapAuth = await IsValidLDAPAuth(username, password);
|
||||
// let validLdapAuth = await IsValidLDAPAuth(username, password);
|
||||
let validLdapAuth = await IsValidLDAPAuth(userLdapName, password);
|
||||
if (validLdapUser && (validLdapAuth || IsValidOldSecret(username, password) || IsValidJWT(username, password))) {
|
||||
// if (IsValidOldSecret(username, password) || IsValidJWT(username, password)) {
|
||||
res.status(200).json(null);
|
||||
|
||||
res.status(200).json(finalProfile);
|
||||
} else {
|
||||
res.status(401).json(null);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ module.exports = {
|
||||
pass: "oolehohqueithaipeikahtaeshoozais",
|
||||
idleTimeoutMillis: 10000,
|
||||
connectionTimeoutMillis: 10000
|
||||
}
|
||||
}
|
||||
},
|
||||
development2: {
|
||||
xmppToken: 'irithep1KeiViemohmui3fo3eiyeitah',
|
||||
@@ -56,7 +56,7 @@ module.exports = {
|
||||
},
|
||||
gr13: {
|
||||
servicePort: 9544,
|
||||
xmppToken: 'ocu8saithoYa2teeb2ahTh9fee4is7ai',
|
||||
xmppToken: 'ocu8saithoYa2teeb2ahTh9fee4is7ai',
|
||||
ldap: {
|
||||
ldapUri: 'ldap://192.168.21.142:389',
|
||||
bindDn: 'uid=zimbra,cn=admins,cn=zimbra',
|
||||
@@ -75,6 +75,15 @@ module.exports = {
|
||||
pass: "vahG7ooli7thee0iek4Ewoo9Sai6oWah",
|
||||
idleTimeoutMillis: 10000,
|
||||
connectionTimeoutMillis: 10000
|
||||
},
|
||||
vncproject: {
|
||||
host: "192.168.21.205",
|
||||
port: 5432,
|
||||
name: "redmineproddb",
|
||||
user: "redmineprod",
|
||||
pass: "fßßb4redProd",
|
||||
idleTimeoutMillis: 10000,
|
||||
connectionTimeoutMillis: 10000
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user