This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
mandayejs/mandayejs/do_login.js

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);
}
});