| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 |
- function Console() {}
- Console.Type = {
- LOG: "log",
- DEBUG: "debug",
- INFO: "info",
- WARN: "warn",
- ERROR: "error",
- GROUP: "group",
- GROUP_COLLAPSED: "groupCollapsed",
- GROUP_END: "groupEnd"
- };
- Console.addMessage = function(type, format, args) {
- chrome.runtime.sendMessage({
- command: "sendToConsole",
- tabId: chrome.devtools.inspectedWindow.tabId,
- args: escape(JSON.stringify(Array.prototype.slice.call(arguments, 0)))
- });
- };
- // Generate Console output methods, i.e. Console.log(), Console.debug() etc.
- (function() {
- var console_types = Object.getOwnPropertyNames(Console.Type);
- for (var type = 0; type < console_types.length; ++type) {
- var method_name = Console.Type[console_types[type]];
- Console[method_name] = Console.addMessage.bind(Console, method_name);
- }
- })();
- SAMLChrome.controller('PanelController', function PanelController($scope, $http, toolbar) {
- $scope.uniqueid = 1000000;
- $scope.activeId = null;
- $scope.requests = {};
- $scope.showSamlRequests = {};
- $scope.showAll = false;
- $scope.limitNetworkRequests = true;
- $scope.showOriginalSAML = false;
- $scope.currentDetailTab = "tab-saml";
- $scope.myCodeMirror = null;
- $scope.activeCookies = [];
- $scope.activeHeaders = [];
- $scope.activePostData = [];
- $scope.activeRequest = [];
- $scope.activeResponseData = [];
- $scope.activeResponseCookies = [];
- $scope.activeResponseHeaders = [];
- $scope.activeSaml = null;
- $scope.showIncomingRequests = true;
- $scope.init = function(type) {
- $('#tabs').tabs();
- $scope.initChrome();
- this.createToolbar();
- };
- $scope.initChrome = function() {
- key('⌘+k, ctrl+l', function() {
- $scope.$apply(function() {
- $scope.clear();
- });
- });
- chrome.devtools.network.onRequestFinished.addListener(function(request) {
- // do not show requests to chrome extension resources
- if (request.request.url.startsWith("chrome-extension://")) {
- return;
- }
- $scope.handleSAMLHeaders(request);
- });
- };
- $scope.handleSAMLHeaders = function(har_entry) {
- let decoded_saml_message;
- const request_method = har_entry.request.method;
- const request_url = har_entry.request.url;
- const response_status = har_entry.response.status;
- const saml_request_string = "SAMLRequest=";
- const saml_response_string = "SAMLResponse=";
- let found_saml = false;
- var index_of_saml_request_string = request_url.indexOf(saml_request_string);
- if (index_of_saml_request_string > -1) {
- Console.log("SAML Request Method: " + request_method);
- Console.log("SAML Request URL: " + request_url);
- var index_of_next_param = request_url.indexOf("&", index_of_saml_request_string);
- if (index_of_next_param < 0) {
- index_of_next_param = request_url.length;
- }
- //assumes that the GET request is http(s)://host/sso/idp?SAMLRequest=xxxxx&RelayState=yyyy
- const saml_message = request_url.substr(index_of_saml_request_string + saml_request_string.length, index_of_next_param - (index_of_saml_request_string + saml_request_string.length));
- //requires inflating
- decoded_saml_message = RawDeflate.inflate(window.atob(unescape(saml_message)));
- $scope.addRequest(har_entry, request_method, request_url, response_status, decoded_saml_message);
- Console.log("SAML Request Data: " + decoded_saml_message);
- found_saml = true;
- }
- let har_post_data = null;
- if (har_entry.request != null && har_entry.request.postData != null) {
- har_post_data = har_entry.request.postData.text;
- };
- if (har_post_data != null) {
- if (har_post_data.indexOf(saml_request_string) > -1) {
- decoded_saml_message = $scope.getDecodedSamlMessageFromPostData("Request", request_method, request_url, har_post_data, saml_request_string, response_status, har_entry);
- Console.log("SAML Request Data: " + decoded_saml_message);
- found_saml = true;
- } else if (har_post_data.indexOf(saml_response_string) > -1) {
- decoded_saml_message = $scope.getDecodedSamlMessageFromPostData("Response", request_method, request_url, har_post_data, saml_response_string, response_status, har_entry);
- Console.log("SAML Response Data: " + decoded_saml_message);
- found_saml = true;
- }
- }
- if (found_saml === false) {
- $scope.addRequest(har_entry, request_method, request_url, response_status, null);
- }
- };
- $scope.getDecodedSamlMessageFromPostData = function(request_response_string, request_method, request_url, har_post_data, saml_string, response_status, har_entry) {
- const index_of_saml_string = har_post_data.indexOf(saml_string);
- let saml_message = har_post_data.substr(index_of_saml_string + saml_string.length, har_post_data.length - (index_of_saml_string + saml_string.length));
- const index_of_next_param = saml_message.indexOf("&", 0);
- if (index_of_next_param > -1) {
- saml_message = saml_message.substr(0, index_of_next_param);
- }
- //using the window.atob base64 decoding method as it seems to work pretty well
- const decoded_saml_message = window.atob(unescape(saml_message));
- $scope.addRequest(har_entry, request_method, request_url, response_status, decoded_saml_message);
- return decoded_saml_message;
- };
- $scope.createToolbar = function() {
- toolbar.createButton('search', 'Search SAML', false, function() {
- $scope.$apply(function() {
- if ($scope.myCodeMirror) {
- $scope.myCodeMirror.execCommand("find");
- }
- });
- });
- toolbar.createToggleButton('file-text-o', 'SAML Format', false, function() {
- $scope.$apply(function() {
- $scope.showOriginalSAML = !$scope.showOriginalSAML;
- $scope.displaySaml();
- });
- }, false);
- toolbar.createButton('chain', 'Update All Link/Form Targets to _self', false, function() {
- $scope.$apply(function() {
- chrome.runtime.sendMessage({
- command: "scrub",
- tabId: chrome.devtools.inspectedWindow.tabId
- });
- });
- });
- toolbar.createButton('download', 'Export', false, function() {
- $scope.$apply(function() {
- var blob = new Blob([JSON.stringify($scope.requests)], {type: "application/json;charset=utf-8"});
- saveAs(blob, "SAMLChromeExport.json");
- });
- });
- toolbar.createButton('upload', 'Import', true, function() {
- $scope.$apply(function() {
- $('#ImportInput').click();
- });
- });
- toolbar.createToggleButton('tasks', 'SAML Filter', false, function() {
- $scope.$apply(function() {
- $scope.showAll = !$scope.showAll;
- $scope.showTraffic();
- });
- }, false);
- toolbar.createToggleButton('list', 'Limit network requests to 500', false, function() {
- $scope.$apply(function() {
- $scope.limitNetworkRequests = !$scope.limitNetworkRequests;
- });
- }, true);
- toolbar.createButton('ban', 'Clear', false, function() {
- $scope.$apply(function() {
- $scope.clear();
- });
- });
- $('.toolbar').replaceWith(toolbar.render());
- //clears the input value so you can reload the same file
- document.getElementById('ImportInput').addEventListener('click', function() {this.value=null;}, false);
- document.getElementById('ImportInput').addEventListener('change', readFile, false);
- function readFile (evt) {
- const files = evt.target.files;
- const file = files[0];
- const reader = new FileReader();
- reader.onload = function() {
- $scope.importFile(this.result);
- }
- reader.readAsText(file)
- }
- };
- $scope.importFile = function(data) {
- $scope.$apply(function() {
- const importHar = JSON.parse(data);
- for (i in importHar)
- {
- $scope.handleSAMLHeaders(importHar[i]);
- }
- });
- }
- $scope.addRequest = function(data, request_method, request_url, response_status, decoded_saml_message) {
- $scope.$apply(function() {
- const requestId = $scope.uniqueid;
- $scope.uniqueid = $scope.uniqueid + 1;
- if (data.request != null) {
- data["request_data"] = $scope.createKeypairs(data.request);
- if (data.request.cookies != null) {
- data.cookies = $scope.createKeypairsDeep(data.request.cookies);
- }
- if (data.request.headers != null) {
- data.headers = $scope.createKeypairsDeep(data.request.headers);
- }
- if (data.request.postData != null) {
- data.postData = $scope.createKeypairsDeep(data.request.postData.params);
- }
- }
- if (data.response != null) {
- data["response_data"] = $scope.createKeypairs(data.response);
- if (data.response.cookies != null) {
- data["response_cookies"] = $scope.createKeypairsDeep(data.response.cookies);
- }
- if (data.response.headers != null) {
- data["response_headers"] = $scope.createKeypairsDeep(data.response.headers);
- }
- }
- data["request_method"] = request_method;
- data["request_url"] = request_url;
- data["response_status"] = response_status;
- data["id"] = requestId;
- data["saml"] = decoded_saml_message;
- $scope.requests[requestId] = data;
- if (decoded_saml_message != null || $scope.showAll === true) {
- $scope.showSamlRequests[requestId] = data;
- }
- $scope.cleanRequests();
- if ($scope.showIncomingRequests && $scope.showSamlRequests[requestId]) {
- $scope.setActive(requestId);
- }
- });
- };
- $scope.cleanRequests = function() {
- if ($scope.limitNetworkRequests === true) {
- const keys = Object.keys($scope.requests).reverse().slice(500);
- keys.forEach(function(key) {
- if ($scope.requests[key]) {
- delete $scope.requests[key];
- }
- if ($scope.showSamlRequests[key]) {
- delete $scope.showSamlRequests[key];
- }
- });
- }
- }
- $scope.clear = function() {
- $scope.requests = {};
- $scope.activeId = null;
- $scope.showSamlRequests = {};
- $scope.activeCookies = [];
- $scope.activeHeaders = [];
- $scope.activePostData = [];
- $scope.activeRequest = [];
- $scope.activeResponseData = [];
- $scope.activeResponseCookies = [];
- $scope.activeResponseHeaders = [];
- $scope.activeSaml = null;
- $scope.showIncomingRequests = true;
- document.getElementById("tab-saml-codemirror").style.visibility = "hidden";
- };
- $scope.setActive = function(requestId) {
- if (!$scope.requests[requestId]) {
- return;
- }
- $scope.activeId = requestId;
- $scope.activeCookies = $scope.requests[requestId].cookies;
- $scope.activeHeaders = $scope.requests[requestId].headers;
- $scope.activePostData = $scope.requests[requestId].postData;
- $scope.activeRequest = $scope.requests[requestId].request_data;
- $scope.activeResponseData = $scope.requests[requestId].response_data;
- $scope.activeResponseCookies = $scope.requests[requestId].response_cookies;
- $scope.activeResponseHeaders = $scope.requests[requestId].response_headers;
- $scope.activeSaml = $scope.requests[requestId].saml;
- const lastRequestId = Object.keys($scope.showSamlRequests)[Object.keys($scope.showSamlRequests).length - 1];
- $scope.showIncomingRequests = requestId == lastRequestId;
- if ($scope.activeSaml == null && $scope.currentDetailTab === "tab-saml") {
- $("#tabs").tabs("option", "active", $("tab-request" + "Selector").index() - 1);
- }
- };
- $scope.getClass = function(requestId) {
- if (requestId === $scope.activeId) {
- return 'selected';
- } else {
- return '';
- }
- };
- $scope.showTraffic = function() {
- $scope.showSamlRequests = {};
- $.each($scope.requests, function(request) {
- if ($scope.requests[request].saml != null || $scope.showAll === true) {
- $scope.showSamlRequests[request] = $scope.requests[request];
- }
- });
- var lastRequestId = Object.keys($scope.showSamlRequests)[Object.keys($scope.showSamlRequests).length - 1];
- $scope.showIncomingRequests = $scope.activeId == lastRequestId;
- }
- $scope.createKeypairs = function(data) {
- let keypairs = [];
- if (!(data instanceof Object)) {
- return keypairs;
- }
- $.each(data, function(key, value) {
- if (!(value instanceof Object)) {
- keypairs.push({
- name: key,
- value: value
- });
- }
- });
- return keypairs;
- };
- $scope.createKeypairsDeep = function(data) {
- let keypairs = [];
- if (!(data instanceof Object)) {
- return keypairs;
- }
- $.each(data, function(key, value) {
- keypairs.push({
- name: value.name,
- value: value.value
- });
- });
- return keypairs;
- };
- $scope.$watch('activeSaml', function() {
- $scope.displaySaml();
- });
- $scope.isSaml = function(requestId) {
- if ($scope.requests[requestId].saml != null) {
- return "saml";
- }
- }
- $scope.getTrafficStyle = function(request) {
- if (request.saml != null) {
- const status = request.response_status;
- if (status >= 200 && status < 300) {
- return "success";
- } else if (status >= 300 && status < 400) {
- return "redirect";
- } else {
- return "error"
- }
- }
- return "";
- }
- $scope.selectDetailTab = function(tabId) {
- $scope.currentDetailTab = tabId;
- if (tabId === "tab-saml") {
- $scope.displaySaml();
- }
- }
- $scope.displaySaml = function() {
- if ($scope.activeSaml != null) {
- document.getElementById("tab-saml-codemirror").style.visibility = "visible";
- let samlContent = $scope.activeSaml;
- if (!$scope.showOriginalSAML) {
- samlContent = $scope.getPrettyXML(samlContent);
- }
- if ($scope.myCodeMirror) {
- $scope.myCodeMirror.getDoc().setValue(samlContent);
- return;
- }
- document.getElementById("tab-saml-codemirror").innerHTML = "";
- const myCodeMirror = CodeMirror(document.getElementById("tab-saml-codemirror"), {
- value: samlContent,
- mode: "xml",
- lineNumbers: true,
- lineWrapping: true
- });
- $scope.myCodeMirror = myCodeMirror;
- }
- }
- $scope.getPrettyXML = function(source) {
- return new XmlBeautify().beautify(source,
- {
- indent: " ", //indent pattern like white spaces
- useSelfClosingElement: false //true:use self-closing element when empty element.
- });
- }
- });
|