You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
623 lines
20 KiB
623 lines
20 KiB
// Generated by CoffeeScript 1.12.8
|
|
|
|
/*
|
|
* Sessions explorer
|
|
*/
|
|
|
|
(function() {
|
|
var categories, hiddenAttributes, llapp, max, menu, overScheme, schemes;
|
|
|
|
max = 25;
|
|
|
|
schemes = {
|
|
_whatToTrace: [
|
|
function(t, v) {
|
|
return "groupBy=substr(" + t + ",1)";
|
|
}, function(t, v) {
|
|
return t + "=" + v + "*&groupBy=" + t;
|
|
}, function(t, v) {
|
|
return t + "=" + v;
|
|
}
|
|
],
|
|
ipAddr: [
|
|
function(t, v) {
|
|
return "groupBy=net(" + t + ",16,1)";
|
|
}, function(t, v) {
|
|
if (!v.match(/:/)) {
|
|
v = v + '.';
|
|
}
|
|
return t + "=" + v + "*&groupBy=net(" + t + ",32,2)";
|
|
}, function(t, v) {
|
|
if (!v.match(/:/)) {
|
|
v = v + '.';
|
|
}
|
|
return t + "=" + v + "*&groupBy=net(" + t + ",48,3)";
|
|
}, function(t, v) {
|
|
if (!v.match(/:/)) {
|
|
v = v + '.';
|
|
}
|
|
return t + "=" + v + "*&groupBy=net(" + t + ",128,4)";
|
|
}, function(t, v) {
|
|
return t + "=" + v + "&groupBy=_whatToTrace";
|
|
}, function(t, v, q) {
|
|
return q.replace(/\&groupBy.*$/, '') + ("&_whatToTrace=" + v);
|
|
}
|
|
],
|
|
_startTime: [
|
|
function(t, v) {
|
|
return "groupBy=substr(" + t + ",8)";
|
|
}, function(t, v) {
|
|
return t + "=" + v + "*&groupBy=substr(" + t + ",10)";
|
|
}, function(t, v) {
|
|
return t + "=" + v + "*&groupBy=substr(" + t + ",11)";
|
|
}, function(t, v) {
|
|
return t + "=" + v + "*&groupBy=substr(" + t + ",12)";
|
|
}, function(t, v) {
|
|
return t + "=" + v + "*&groupBy=_whatToTrace";
|
|
}, function(t, v, q) {
|
|
console.log(t);
|
|
console.log(v);
|
|
console.log(q);
|
|
return q.replace(/\&groupBy.*$/, '') + ("&_whatToTrace=" + v);
|
|
}
|
|
],
|
|
doubleIp: [
|
|
function(t, v) {
|
|
return t;
|
|
}, function(t, v) {
|
|
return "_whatToTrace=" + v + "&groupBy=ipAddr";
|
|
}, function(t, v, q) {
|
|
return q.replace(/\&groupBy.*$/, '') + ("&ipAddr=" + v);
|
|
}
|
|
],
|
|
_session_uid: [
|
|
function(t, v) {
|
|
return "groupBy=substr(" + t + ",1)";
|
|
}, function(t, v) {
|
|
return t + "=" + v + "*&groupBy=" + t;
|
|
}, function(t, v) {
|
|
return t + "=" + v;
|
|
}
|
|
]
|
|
};
|
|
|
|
overScheme = {
|
|
_whatToTrace: function(t, v, level, over) {
|
|
console.log('overScheme => level', level, 'over', over);
|
|
if (level === 1 && v.length > over) {
|
|
return t + "=" + v + "*&groupBy=substr(" + t + "," + (level + over + 1) + ")";
|
|
} else {
|
|
return null;
|
|
}
|
|
},
|
|
ipAddr: function(t, v, level, over) {
|
|
console.log('overScheme => level', level, 'over', over);
|
|
if (level > 0 && level < 4 && !v.match(/^\d+\.\d/) && over < 2) {
|
|
return t + "=" + v + "*&groupBy=net(" + t + "," + (16 * level + 4 * (over + 1)) + "," + (1 + level + over) + ")";
|
|
} else {
|
|
return null;
|
|
}
|
|
},
|
|
_startTime: function(t, v, level, over) {
|
|
console.log('overScheme => level', level, 'over', over);
|
|
if (level > 3) {
|
|
return t + "=" + v + "*&groupBy=substr(" + t + "," + (10 + level + over) + ")";
|
|
} else {
|
|
return null;
|
|
}
|
|
},
|
|
_session_uid: function(t, v, level, over) {
|
|
console.log('overScheme => level', level, 'over', over);
|
|
if (level === 1 && v.length > over) {
|
|
return t + "=" + v + "*&groupBy=substr(" + t + "," + (level + over + 1) + ")";
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
hiddenAttributes = '_password';
|
|
|
|
categories = {
|
|
dateTitle: ['_utime', '_startTime', '_updateTime', '_lastAuthnUTime', '_lastSeen'],
|
|
connectionTitle: ['ipAddr', '_timezone', '_url'],
|
|
authenticationTitle: ['_session_id', '_user', '_password', 'authenticationLevel'],
|
|
modulesTitle: ['_auth', '_userDB', '_passwordDB', '_issuerDB', '_authChoice', '_authMulti', '_userDBMulti'],
|
|
saml: ['_idp', '_idpConfKey', '_samlToken', '_lassoSessionDump', '_lassoIdentityDump'],
|
|
groups: ['groups', 'hGroups'],
|
|
ldap: ['dn'],
|
|
BrowserID: ['_browserIdAnswer', '_browserIdAnswerRaw'],
|
|
OpenIDConnect: ['_oidc_id_token', '_oidc_OP', '_oidc_access_token'],
|
|
sfaTitle: ['_2fDevices'],
|
|
oidcConsents: ['_oidcConsents']
|
|
};
|
|
|
|
menu = {
|
|
session: [
|
|
{
|
|
title: 'deleteSession',
|
|
icon: 'trash'
|
|
}
|
|
],
|
|
home: []
|
|
};
|
|
|
|
|
|
/*
|
|
* AngularJS application
|
|
*/
|
|
|
|
llapp = angular.module('llngSessionsExplorer', ['ui.tree', 'ui.bootstrap', 'llApp']);
|
|
|
|
llapp.controller('SessionsExplorerCtrl', [
|
|
'$scope', '$translator', '$location', '$q', '$http', function($scope, $translator, $location, $q, $http) {
|
|
var autoId, c, pathEvent, sessionType;
|
|
$scope.links = links;
|
|
$scope.menulinks = menulinks;
|
|
$scope.staticPrefix = staticPrefix;
|
|
$scope.scriptname = scriptname;
|
|
$scope.formPrefix = formPrefix;
|
|
$scope.impPrefix = impPrefix;
|
|
$scope.sessionTTL = sessionTTL;
|
|
$scope.availableLanguages = availableLanguages;
|
|
$scope.waiting = true;
|
|
$scope.showM = false;
|
|
$scope.showT = true;
|
|
$scope.data = [];
|
|
$scope.currentScope = null;
|
|
$scope.currentSession = null;
|
|
$scope.menu = menu;
|
|
$scope.translateP = $translator.translateP;
|
|
$scope.translate = $translator.translate;
|
|
$scope.translateTitle = function(node) {
|
|
return $translator.translateField(node, 'title');
|
|
};
|
|
sessionType = 'global';
|
|
$scope.menuClick = function(button) {
|
|
if (button.popup) {
|
|
window.open(button.popup);
|
|
} else {
|
|
if (!button.action) {
|
|
button.action = button.title;
|
|
}
|
|
switch (typeof button.action) {
|
|
case 'function':
|
|
button.action($scope.currentNode, $scope);
|
|
break;
|
|
case 'string':
|
|
$scope[button.action]();
|
|
break;
|
|
default:
|
|
console.log(typeof button.action);
|
|
}
|
|
}
|
|
return $scope.showM = false;
|
|
};
|
|
$scope.deleteOIDCConsent = function(rp, epoch) {
|
|
var items;
|
|
items = document.querySelectorAll(".data-" + epoch);
|
|
$scope.waiting = true;
|
|
$http['delete'](scriptname + "sessions/OIDCConsent/" + sessionType + "/" + $scope.currentSession.id + "?rp=" + rp + "&epoch=" + epoch).then(function(response) {
|
|
var e, i, len, results;
|
|
$scope.waiting = false;
|
|
results = [];
|
|
for (i = 0, len = items.length; i < len; i++) {
|
|
e = items[i];
|
|
results.push(e.remove());
|
|
}
|
|
return results;
|
|
}, function(resp) {
|
|
return $scope.waiting = false;
|
|
});
|
|
return $scope.showT = false;
|
|
};
|
|
$scope.deleteSession = function() {
|
|
$scope.waiting = true;
|
|
return $http['delete'](scriptname + "sessions/" + sessionType + "/" + $scope.currentSession.id).then(function(response) {
|
|
$scope.currentSession = null;
|
|
$scope.currentScope.remove();
|
|
return $scope.waiting = false;
|
|
}, function(resp) {
|
|
return $scope.waiting = false;
|
|
});
|
|
};
|
|
$scope.stoggle = function(scope) {
|
|
var node;
|
|
node = scope.$modelValue;
|
|
if (node.nodes.length === 0) {
|
|
$scope.updateTree(node.value, node.nodes, node.level, node.over, node.query, node.count);
|
|
}
|
|
return scope.toggle();
|
|
};
|
|
$scope.displaySession = function(scope) {
|
|
var sessionId, transformSession;
|
|
transformSession = function(session) {
|
|
var _insert, array, attr, attrs, category, cv, element, epoch, i, j, k, key, l, len, len1, len2, len3, len4, len5, m, name, o, oidcConsent, p, real, ref, ref1, res, sfDevice, spoof, subres, tab, time, title, tmp, value;
|
|
_insert = function(re, title) {
|
|
var key, reg, tmp, value;
|
|
tmp = [];
|
|
reg = new RegExp(re);
|
|
for (key in session) {
|
|
value = session[key];
|
|
if (key.match(reg) && value) {
|
|
tmp.push({
|
|
title: key,
|
|
value: value
|
|
});
|
|
delete session[key];
|
|
}
|
|
}
|
|
if (tmp.length > 0) {
|
|
return res.push({
|
|
title: title,
|
|
nodes: tmp
|
|
});
|
|
}
|
|
};
|
|
time = session._utime;
|
|
for (key in session) {
|
|
value = session[key];
|
|
if (!value) {
|
|
delete session[key];
|
|
} else {
|
|
if (typeof session === 'string' && value.match(/; /)) {
|
|
session[key] = value.split('; ');
|
|
}
|
|
if (typeof session[key] !== 'object') {
|
|
if (hiddenAttributes.match(new RegExp('\b' + key + '\b'))) {
|
|
session[key] = '********';
|
|
} else if (key.match(/^(_utime|_lastAuthnUTime|_lastSeen|notification)$/)) {
|
|
session[key] = $scope.localeDate(value);
|
|
} else if (key.match(/^(_startTime|_updateTime)$/)) {
|
|
session[key] = $scope.strToLocaleDate(value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
res = [];
|
|
for (category in categories) {
|
|
attrs = categories[category];
|
|
subres = [];
|
|
for (i = 0, len = attrs.length; i < len; i++) {
|
|
attr = attrs[i];
|
|
if (session[attr]) {
|
|
if (session[attr].toString().match(/"type":\s*"(?:TOTP|U2F|UBK)"/)) {
|
|
subres.push({
|
|
title: "type",
|
|
value: "name",
|
|
epoch: "date",
|
|
td: "0"
|
|
});
|
|
array = JSON.parse(session[attr]);
|
|
for (j = 0, len1 = array.length; j < len1; j++) {
|
|
sfDevice = array[j];
|
|
for (key in sfDevice) {
|
|
value = sfDevice[key];
|
|
if (key === 'type') {
|
|
title = value;
|
|
}
|
|
if (key === 'name') {
|
|
name = value;
|
|
}
|
|
if (key === 'epoch') {
|
|
epoch = value;
|
|
}
|
|
}
|
|
subres.push({
|
|
title: title,
|
|
value: name,
|
|
epoch: epoch,
|
|
td: "1"
|
|
});
|
|
}
|
|
delete session[attr];
|
|
} else if (session[attr].toString().match(/"rp":\s*"[\w-]+"/)) {
|
|
subres.push({
|
|
title: "RP",
|
|
value: "scope",
|
|
epoch: "date",
|
|
td: "0"
|
|
});
|
|
array = JSON.parse(session[attr]);
|
|
for (k = 0, len2 = array.length; k < len2; k++) {
|
|
oidcConsent = array[k];
|
|
for (key in oidcConsent) {
|
|
value = oidcConsent[key];
|
|
if (key === 'rp') {
|
|
title = value;
|
|
}
|
|
if (key === 'scope') {
|
|
name = value;
|
|
}
|
|
if (key === 'epoch') {
|
|
epoch = value;
|
|
}
|
|
}
|
|
subres.push({
|
|
title: title,
|
|
value: name,
|
|
epoch: epoch,
|
|
td: "2"
|
|
});
|
|
}
|
|
delete session[attr];
|
|
} else if (session[attr].toString().match(/\w+/)) {
|
|
subres.push({
|
|
title: attr,
|
|
value: session[attr],
|
|
epoch: ''
|
|
});
|
|
delete session[attr];
|
|
} else {
|
|
delete session[attr];
|
|
}
|
|
} else {
|
|
delete session[attr];
|
|
}
|
|
}
|
|
if (subres.length > 0) {
|
|
res.push({
|
|
title: "__" + category + "__",
|
|
nodes: subres
|
|
});
|
|
}
|
|
}
|
|
_insert('^openid', 'OpenID');
|
|
_insert('^notification_(.+)', '__notificationsDone__');
|
|
if (session._loginHistory) {
|
|
tmp = [];
|
|
if (session._loginHistory.successLogin) {
|
|
ref = session._loginHistory.successLogin;
|
|
for (m = 0, len3 = ref.length; m < len3; m++) {
|
|
l = ref[m];
|
|
cv = "";
|
|
for (key in l) {
|
|
value = l[key];
|
|
if (!key.match(/^(_utime|ipAddr|error)$/)) {
|
|
cv += ", " + key + " : " + value;
|
|
}
|
|
}
|
|
tab = cv.split(', ');
|
|
tab.sort();
|
|
cv = tab.join(', ');
|
|
tmp.push({
|
|
t: l._utime,
|
|
title: $scope.localeDate(l._utime),
|
|
value: ("Success (IP " + l.ipAddr + ")") + cv
|
|
});
|
|
}
|
|
}
|
|
if (session._loginHistory.failedLogin) {
|
|
ref1 = session._loginHistory.failedLogin;
|
|
for (o = 0, len4 = ref1.length; o < len4; o++) {
|
|
l = ref1[o];
|
|
cv = "";
|
|
for (key in l) {
|
|
value = l[key];
|
|
if (!key.match(/^(_utime|ipAddr|error)$/)) {
|
|
cv += ", " + key + " : " + value;
|
|
}
|
|
}
|
|
tab = cv.split(', ');
|
|
tab.sort();
|
|
cv = tab.join(', ');
|
|
tmp.push({
|
|
t: l._utime,
|
|
title: $scope.localeDate(l._utime),
|
|
value: ("Error " + l.error + " (IP " + l.ipAddr + ")") + cv
|
|
});
|
|
}
|
|
}
|
|
delete session._loginHistory;
|
|
tmp.sort(function(a, b) {
|
|
return b.t - a.t;
|
|
});
|
|
res.push({
|
|
title: '__loginHistory__',
|
|
nodes: tmp
|
|
});
|
|
}
|
|
tmp = [];
|
|
for (key in session) {
|
|
value = session[key];
|
|
tmp.push({
|
|
title: key,
|
|
value: value
|
|
});
|
|
}
|
|
tmp.sort(function(a, b) {
|
|
if (a.title > b.title) {
|
|
return 1;
|
|
} else if (a.title < b.title) {
|
|
return -1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
});
|
|
real = [];
|
|
spoof = [];
|
|
for (p = 0, len5 = tmp.length; p < len5; p++) {
|
|
element = tmp[p];
|
|
if (element.title.match(new RegExp('^' + $scope.impPrefix + '.+$'))) {
|
|
console.log(element, '-> real attribute');
|
|
real.push(element);
|
|
} else {
|
|
spoof.push(element);
|
|
}
|
|
}
|
|
tmp = spoof.concat(real);
|
|
res.push({
|
|
title: '__attributesAndMacros__',
|
|
nodes: tmp
|
|
});
|
|
return {
|
|
_utime: time,
|
|
nodes: res
|
|
};
|
|
};
|
|
$scope.currentScope = scope;
|
|
sessionId = scope.$modelValue.session;
|
|
$http.get(scriptname + "sessions/" + sessionType + "/" + sessionId).then(function(response) {
|
|
$scope.currentSession = transformSession(response.data);
|
|
return $scope.currentSession.id = sessionId;
|
|
});
|
|
return $scope.showT = false;
|
|
};
|
|
$scope.localeDate = function(s) {
|
|
var d;
|
|
d = new Date(s * 1000);
|
|
return d.toLocaleString();
|
|
};
|
|
$scope.isValid = function(epoch, type) {
|
|
var isValid, now, path;
|
|
path = $location.path();
|
|
now = Date.now() / 1000;
|
|
console.log("Path", path);
|
|
console.log("Session epoch", epoch);
|
|
console.log("Current date", now);
|
|
console.log("Session TTL", sessionTTL);
|
|
isValid = now - epoch < sessionTTL || $location.path().match(/^\/persistent/);
|
|
if (type === 'msg') {
|
|
console.log("Return msg");
|
|
if (isValid) {
|
|
return "info";
|
|
} else {
|
|
return "warning";
|
|
}
|
|
} else if (type === 'style') {
|
|
console.log("Return style");
|
|
if (isValid) {
|
|
return {};
|
|
} else {
|
|
return {
|
|
'color': '#627990',
|
|
'font-style': 'italic'
|
|
};
|
|
}
|
|
} else {
|
|
console.log("Return isValid");
|
|
return isValid;
|
|
}
|
|
};
|
|
$scope.strToLocaleDate = function(s) {
|
|
var arrayDate, d;
|
|
arrayDate = s.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/);
|
|
if (!arrayDate.length) {
|
|
return s;
|
|
}
|
|
d = new Date(arrayDate[1] + "-" + arrayDate[2] + "-" + arrayDate[3] + "T" + arrayDate[4] + ":" + arrayDate[5] + ":" + arrayDate[6]);
|
|
return d.toLocaleString();
|
|
};
|
|
$scope.getLanguage = function(lang) {
|
|
$scope.lang = lang;
|
|
$scope.form = 'white';
|
|
$scope.init();
|
|
return $scope.showM = false;
|
|
};
|
|
pathEvent = function(event, next, current) {
|
|
var n;
|
|
n = next.match(/#!?\/(\w+)/);
|
|
sessionType = 'global';
|
|
if (n === null) {
|
|
$scope.type = '_whatToTrace';
|
|
} else if (n[1].match(/^(persistent|offline)$/)) {
|
|
sessionType = RegExp.$1;
|
|
$scope.type = '_session_uid';
|
|
} else {
|
|
$scope.type = n[1];
|
|
}
|
|
return $scope.init();
|
|
};
|
|
$scope.$on('$locationChangeSuccess', pathEvent);
|
|
autoId = 0;
|
|
$scope.updateTree = function(value, node, level, over, currentQuery, count) {
|
|
var query, scheme, tmp;
|
|
$scope.waiting = true;
|
|
scheme = schemes[$scope.type] ? schemes[$scope.type] : $scope.type === '_updateTime' ? schemes._startTime : schemes._whatToTrace;
|
|
query = scheme[level]($scope.type, value, currentQuery);
|
|
if (count > max && overScheme[$scope.type]) {
|
|
if (tmp = overScheme[$scope.type]($scope.type, value, level, over, currentQuery)) {
|
|
over++;
|
|
query = tmp;
|
|
level = level - 1;
|
|
} else {
|
|
over = 0;
|
|
}
|
|
} else {
|
|
over = 0;
|
|
}
|
|
$http.get(scriptname + "sessions/" + sessionType + "?" + query).then(function(response) {
|
|
var data, i, len, n, ref;
|
|
data = response.data;
|
|
if (data.result) {
|
|
ref = data.values;
|
|
for (i = 0, len = ref.length; i < len; i++) {
|
|
n = ref[i];
|
|
autoId++;
|
|
n.id = "node" + autoId;
|
|
if (level < scheme.length - 1) {
|
|
n.nodes = [];
|
|
n.level = level + 1;
|
|
n.query = query;
|
|
n.over = over;
|
|
if ($scope.type.match(/^(?:start|update)Time$/)) {
|
|
n.title = n.value.replace(/^(\d{8})(\d{2})(\d{2})$/, '$2:$3').replace(/^(\d{8})(\d{2})(\d)$/, '$2:$30').replace(/^(\d{8})(\d{2})$/, '$2h').replace(/^(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
|
|
}
|
|
}
|
|
node.push(n);
|
|
}
|
|
if (value === '') {
|
|
$scope.total = data.total;
|
|
}
|
|
}
|
|
return $scope.waiting = false;
|
|
}, function(resp) {
|
|
return $scope.waiting = false;
|
|
});
|
|
console.log("Selection", sessionType);
|
|
$scope.navssoStyle = {
|
|
color: '#777'
|
|
};
|
|
$scope.offlineStyle = {
|
|
color: '#777'
|
|
};
|
|
$scope.persistentStyle = {
|
|
color: '#777'
|
|
};
|
|
if (sessionType === 'global') {
|
|
$scope.navssoStyle = {
|
|
color: '#333'
|
|
};
|
|
}
|
|
if (sessionType === 'offline') {
|
|
$scope.offlineStyle = {
|
|
color: '#333'
|
|
};
|
|
}
|
|
if (sessionType === 'persistent') {
|
|
return $scope.persistentStyle = {
|
|
color: '#333'
|
|
};
|
|
}
|
|
};
|
|
$scope.init = function() {
|
|
$scope.waiting = true;
|
|
$scope.data = [];
|
|
$scope.currentScope = null;
|
|
$scope.currentSession = null;
|
|
$q.all([$translator.init($scope.lang), $scope.updateTree('', $scope.data, 0, 0)]).then(function() {
|
|
return $scope.waiting = false;
|
|
}, function(resp) {
|
|
return $scope.waiting = false;
|
|
});
|
|
$scope.activeModule = "sessions";
|
|
return $scope.myStyle = {
|
|
color: '#ffb84d'
|
|
};
|
|
};
|
|
c = $location.path().match(/^\/(\w+)/);
|
|
return $scope.type = c ? c[1] : '_whatToTrace';
|
|
}
|
|
]);
|
|
|
|
}).call(this);
|
|
|