156 lines
4.9 KiB
JavaScript
156 lines
4.9 KiB
JavaScript
/* mandayejs - saml reverse proxy
|
|
* Copyright (C) 2015 Entr'ouvert
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
* under the terms of the GNU Affero General Public License as published
|
|
* by the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
var page = require('webpage').create();
|
|
var system = require('system');
|
|
|
|
var input = JSON.parse(system.stdin.read(2000)); // no .readAll()...
|
|
|
|
headers_list = [];
|
|
|
|
var output = {'stderr': null, 'result': null };
|
|
var timer = 0;
|
|
|
|
function mandaye_exit(message){
|
|
console.log('<mandayejs>'+message+'</mandayejs>')
|
|
phantom.exit()
|
|
}
|
|
|
|
page.onResourceReceived = function(response){
|
|
if (response.url === input.address && response.status > 399){
|
|
output['result'] = 'page not found';
|
|
output['status_code'] = response.status
|
|
mandaye_exit(JSON.stringify(output));
|
|
}
|
|
for (var i=0; i < response.headers.length; i++){
|
|
var c_header = response.headers[i];
|
|
if (c_header['name'] === 'Set-Cookie'){
|
|
headers_list.push(c_header);
|
|
}
|
|
}
|
|
}
|
|
|
|
page.viewportSize = {width: 1280, height: 1024};
|
|
|
|
page.onError = function(msg, trace){
|
|
var err_stack = ['ERROR: ' + msg];
|
|
|
|
if (trace && trace.length) {
|
|
err_stack.push('TRACE:');
|
|
trace.forEach(function(t) {
|
|
err_stack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
|
|
});
|
|
}
|
|
output['stderr'] = err_stack.join('\n')
|
|
}
|
|
|
|
page.open(input.address, function(status) {
|
|
if (status !== 'success'){
|
|
output['result'] = 'failed to open resource';
|
|
mandaye_exit(JSON.stringify(output));
|
|
}
|
|
|
|
function check_auth(page) {
|
|
input.auth_success = page.evaluate(function() {
|
|
return auth_success();
|
|
});
|
|
input.auth_failure = page.evaluate(function() {
|
|
if (typeof(auth_failure) == 'function')
|
|
return auth_failure();
|
|
return undefined;
|
|
});
|
|
input.password_change_required = page.evaluate(function() {
|
|
if (typeof(password_change_required) == 'function')
|
|
return password_change_required();
|
|
return false;
|
|
});
|
|
|
|
output['headers'] = headers_list;
|
|
output['cookies'] = page.cookies;
|
|
|
|
if (input.password_change_required) {
|
|
output['result'] = 'redirect';
|
|
output['reason'] = 'password_change_required';
|
|
output['url'] = page.url;
|
|
mandaye_exit(JSON.stringify(output));
|
|
}
|
|
|
|
if (input.auth_failure == undefined) {
|
|
if (input.auth_success) {
|
|
output['result'] = 'ok';
|
|
output['url'] = page.frameUrl;
|
|
} else {
|
|
output['result'] = 'failure';
|
|
output['reason'] = 'authentication';
|
|
output['url'] = page.frameUrl;
|
|
}
|
|
mandaye_exit(JSON.stringify(output));
|
|
}
|
|
|
|
// run repeatedly the function, if authentication did not
|
|
// succeed and did not fail
|
|
if (!input.auth_success && !input.auth_failure)
|
|
return;
|
|
|
|
if (input.auth_failure) {
|
|
output['result'] = 'failure';
|
|
output['reason'] = 'authentication';
|
|
if (input.auth_success) {
|
|
output['result'] = 'error';
|
|
output['reason'] = 'auth success and failure';
|
|
}
|
|
}
|
|
|
|
if (input.auth_success) {
|
|
output['result'] = 'ok';
|
|
output['url'] = page.frameUrl;
|
|
}
|
|
mandaye_exit(JSON.stringify(output));
|
|
}
|
|
|
|
page.onLoadStarted = function() {
|
|
// reset authentication check when the page reloads
|
|
clearInterval(timer);
|
|
}
|
|
|
|
page.onLoadFinished = function() {
|
|
if (page.injectJs(input.auth_checker))
|
|
timer = setInterval(check_auth, 100, page);
|
|
}
|
|
|
|
page.evaluate(function(input) {
|
|
var locators = input.locators;
|
|
for ( var i=0; i < locators.length; i++ ) {
|
|
locator = locators[i];
|
|
for ( var key in locator ){
|
|
if (locator.hasOwnProperty(key)){
|
|
$(key).val(locator[key]);
|
|
}
|
|
}
|
|
}
|
|
var validate_button = $(key).parents('form').find(input.form_submit_element);
|
|
if (validate_button.length > 0)
|
|
validate_button.click();
|
|
else
|
|
$(input.form_submit_element).click();
|
|
}, input);
|
|
|
|
if (page.injectJs(input.auth_checker)) {
|
|
timer = setInterval(check_auth, 100, page);
|
|
}
|
|
});
|