Skip to content

Instantly share code, notes, and snippets.

@dobesv
Last active July 31, 2018 16:37
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save dobesv/fd70974421b891b3f277 to your computer and use it in GitHub Desktop.
Save dobesv/fd70974421b891b3f277 to your computer and use it in GitHub Desktop.
Login script for custom auth0 database to auth via WordPress XML-RPC

You must provide the following configuration variables:

  1. WP_XMLRPC_URL = https://www.yourdomain.com/xmlrpc.php (replace with your domain and use http:// if you don't have SSL support)
  2. WP_ADMIN_USER = admin (use your own admin username)
  3. WP_ADMIN_PASSWORD = somepassword (use your own admin password)
function getByEmail (name, callback) {
var xpath = require('xpath')
, xmldom = require('xmldom')
, xml2js = require('xml2js');
var dom = xmldom.DOMParser;
var builder = new xml2js.Builder();
var reqXml = builder.buildObject({'methodCall':{
'methodName':'wp.getUsers',
'params':[
{'param':{'value':{'i4':0}}},
{'param':{'value':configuration.WP_ADMIN_USER}},
{'param':{'value':configuration.WP_ADMIN_PASSWORD}}
]
}});
request.post({
url: configuration.WP_XMLRPC_URL,
body: reqXml,
encoding: 'utf8',
method: 'POST',
headers: { 'Content-Type' : 'application/xml' }
}, function (err, response, body) {
if (err) return callback(err);
var parser = new xml2js.Parser();
return parser.parseString(body, function(err, doc) {
if(err) return callback(err);
var mr = doc.methodResponse;
if('fault' in mr) {
if(mr.fault[0].value[0].struct[0].member[0].value[0].int[0] === '403') {
return callback(new WrongUsernameOrPasswordError(configuration.WP_ADMIN_USER, mr.fault[0].value[0].struct[0].member[1].value[0].string[0]));
} else {
return callback(new Error(mr.fault[0].value[0].struct[0].member[1].value[0].string[0]));
}
} else {
var userdatas = mr.params[0].param[0].value[0].array[0].data[0].value;
var userlist = userdatas.map(function(userdata) {
var result = {
user_id: null,
username: null,
nickname: null,
email: null,
display_name: null,
nicename: null,
first_name: null,
last_name: null
};
userdata.struct[0].member.forEach(function(prop) {
if(prop.name[0] in result) {
result[prop.name[0]] = prop.value[0].string[0];
}
});
result.given_name = result.first_name;
result.family_name = result.last_name;
return result;
});
var matches = userlist.filter(function(u) {
return u.email === name || u.username === name;
});
if(matches.length > 0) {
return callback(null, matches[0]);
}
return callback(new ValidationError("not-found", "No matching user found"));
}
});
});
}
function login (email, password, callback) {
var xpath = require('xpath')
, xmldom = require('xmldom')
, xml2js = require('xml2js');
var dom = xmldom.DOMParser;
var builder = new xml2js.Builder();
var reqXml = builder.buildObject({'methodCall':{
'methodName':'wp.getProfile',
'params':[
{'param':{'value':{'i4':0}}},
{'param':{'value':email}},
{'param':{'value':password}}
]
}});
request.post({
url: configuration.WP_XMLRPC_URL,
body: reqXml,
encoding: 'utf8',
method: 'POST',
headers: { 'Content-Type' : 'application/xml', 'Accept' : 'application/xml' }
}, function (err, response, body) {
if (err) return callback(err);
var parser = new xml2js.Parser();
return parser.parseString(body, function(err, doc) {
if(err) return callback(err);
var mr = doc.methodResponse;
if(typeof(mr) === 'undefined') {
throw new Error(JSON.stringify(mr)+" <-- "+body);
}
if('fault' in mr) {
if(mr.fault[0].value[0].struct[0].member[0].value[0].int[0] === '403') {
return callback(new WrongUsernameOrPasswordError(email, mr.fault[0].value[0].struct[0].member[1].value[0].string[0]));
} else {
return callback(new Error(mr.fault[0].value[0].struct[0].member[1].value[0].string[0]));
}
} else {
var result = {
user_id: null,
username: null,
nickname: null,
email: null,
email_verified: true
};
mr.params[0].param[0].value[0].struct[0].member.forEach(function(prop) {
if(prop.name[0] in result) {
result[prop.name[0]] = prop.value[0].string[0];
}
});
if(result.user_id === null ||
result.username === null ||
result.nickname === null ||
result.email === null) {
return callback(new Error("Failed to parse login response: "+JSON.stringify(doc)));
}
return callback(null, result);
}
});
});
}
@glena
Copy link

glena commented May 27, 2015

you use this custom script to import your wordpress users to your Auth0 account, right?

@dobesv
Copy link
Author

dobesv commented Jun 4, 2015

Yes, that's right. It will refer back to WordPress for any username/password user it doesn't recognize.

@dobesv
Copy link
Author

dobesv commented Jun 4, 2015

I just fixed a problem with the script where it wasn't returning a username and changed it to use some libraries to avoid possible encode/decode issues. New and improved!

@dobesv
Copy link
Author

dobesv commented Jun 4, 2015

Also now I added the "getByEmail" script. You'll have to provide login information for an admin user.

@dleeward
Copy link

Where does this script go in Auth0? Rules? Apps?
What does the getByEmail script do? Is it required?
If we are blocking Brute Force XMLRPC calls, is this going to work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment