prevent script tags inside of error popup
[plstackapi.git] / planetstack / core / xoslib / static / js / xoslib / xos-util.js
index d03ab14..6f4db85 100644 (file)
@@ -1,5 +1,40 @@
 // misc utility functions
 
+function idInArray(id, arr) {
+    // because sometimes ids are strings and sometimes they're integers
+    for (index in arr) {
+        if (id.toString() == arr[index].toString()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+function assert(outcome, description) {
+    if (!outcome) {
+        console.log(description);
+    }
+}
+
+function templateFromId(id) {
+    return _.template($(id).html());
+}
+
+function firstCharUpper(s) {
+    return s.charAt(0).toUpperCase() + s.slice(1);
+}
+
+function toTitleCase(str)
+{\r
+    return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});\r
+}
+
+function fieldNameToHumanReadable(str)
+{
+    str = str.replace("_", " ");
+    return toTitleCase(str);
+}
+
 // http://stackoverflow.com/questions/2117320/set-maximum-displayed-rows-count-for-html-table
 function limitTableRows(tableSelector, maxRows) {
     var table = $(tableSelector)[0] //document.getElementById(tableId);
@@ -22,7 +57,7 @@ function limitTableRows(tableSelector, maxRows) {
     }
 }
 
-function validateField(validatorName, value) {
+function validateField(validatorName, value, obj) {
     if (validatorName=="notBlank") {
         if ((value==undefined) || (value=="")) {
             return "can not be blank";
@@ -40,6 +75,184 @@ function validateField(validatorName, value) {
                 return "must be a valid url";
             }
             break;
+
+        case "portspec":
+            if (! $.trim(value).match(portlist_regexp())) {
+                return "must be a valid portspec (example: 'tcp 123, udp 456-789')"
+            }
+            break;
     }
+
     return true;
 }
+
+function array_diff(a1, a2)
+{\r
+  var a=[], diff=[];\r
+  for(var i=0;i<a1.length;i++)\r
+    a[a1[i]]=true;\r
+  for(var i=0;i<a2.length;i++)\r
+    if(a[a2[i]]) delete a[a2[i]];\r
+    else a[a2[i]]=true;\r
+  for(var k in a)\r
+    diff.push(k);\r
+  return diff;\r
+}
+
+function array_subtract(a1, a2)
+{
+    result=[]
+    for (index in a1) {
+        value = a1[index];
+        if (!$.inArray(value, a2) >= 0) {
+            result.push(value);
+        }
+    }
+    return result;
+}
+
+function array_same_elements(arr1, arr2)
+{
+    // return true if arrays have same elements, even if order is different
+    return ($(arr1).not(arr2).length == 0 && $(arr2).not(arr1).length == 0);
+}
+
+function array_pair_lookup(x, names, values)
+{
+    for (index in values) {
+        if (values[index] == x) {
+            return names[index];
+        }
+    }
+    return "object #" + x;
+}
+
+function all_options(selector) {
+    el = $(selector);
+    result = [];
+    _.each(el.find("option"), function(option) {
+        result.push($(option).val());
+    });
+    return result;
+}
+
+function make_same_width(containerSelector, itemSelector) {
+    var maxWidth = 0;
+    $(containerSelector).find(itemSelector).each( function(index) { maxWidth = Math.max(maxWidth, $(this).width()); });\r
+    console.log(maxWidth);\r
+    $(containerSelector).find(itemSelector).each( function(index) { $(this).width(maxWidth); });
+}
+
+function strip_scripts(s) {
+    var div = document.createElement('div');\r
+    div.innerHTML = s;\r
+    var scripts = div.getElementsByTagName('script');\r
+    var i = scripts.length;\r
+    while (i--) {\r
+      scripts[i].parentNode.removeChild(scripts[i]);\r
+    }\r
+    return div.innerHTML;\r
+  }
+
+function parse_portlist(ports) {
+    /* Support a list of ports in the format "protocol:port, protocol:port, ..."
+        examples:
+            tcp 123
+            tcp 123:133
+            tcp 123, tcp 124, tcp 125, udp 201, udp 202
+
+        User can put either a "/" or a " " between protocol and ports
+        Port ranges can be specified with "-" or ":"
+
+        This is a straightforward port of the code in core/models/network.py
+    */
+
+    var nats = [];
+    if (ports) {
+        parts = ports.split(",")
+        $.each(parts, function(index, part) {
+            part = $.trim(part);
+            if (part.indexOf("/")>=0) {
+                parts2 = part.split("/",2);
+                protocol=parts2[0];
+                ports=parts2[1];
+            } else if (part.indexOf(" ")>=0) {
+                parts2 = part.split(" +",2);
+                protocol=parts2[0];
+                ports=parts2[1];
+            } else {
+                throw 'malformed port specifier ' + part + ', format example: "tcp 123, tcp 201:206, udp 333"';
+            }
+
+            protocol = $.trim(protocol);
+            ports = $.trim(ports);
+
+            console.log(ports);
+
+            if (protocol!="tcp" && protocol!="udp") {
+                throw 'unknown protocol ' + protocol;
+            }
+
+            if (ports.indexOf("-")>=0) {
+                parts2 = ports.split("-");
+                first = parseInt($.trim(parts2[0]));
+                last = parseInt($.trim(parts2[1]));
+                portStr = first + ":" + last;
+            } else if (ports.indexOf(":")>=0) {
+                parts2 = ports.split(":");
+                first = parseInt($.trim(parts2[0]));
+                last = parseInt($.trim(parts2[1]));
+                portStr = first + ":" + last;
+            } else {
+                portStr = parseInt(ports).toString();
+            }
+
+            nats.push( {l4_protocol: protocol, l4_port: portStr} );
+        }); /* end $.each(ports) */
+    }
+    return nats
+}
+
+function portlist_regexp() {
+    /* this constructs the big complicated regexp that validates port
+       specifiers. Saved here in long form, in case we need to change it
+       in the future.
+    */
+
+    paren = function(x) { return "(?:" + x + ")"; }
+    whitespace = " *";
+    protocol = paren("tcp|udp");
+    protocolSlash = protocol + paren(whitespace + "|\/");
+    numbers = paren("[0-9]+");
+    range = paren(numbers + paren("-|:") + numbers);
+    numbersOrRange = paren(numbers + "|" + range);
+    protoPorts = paren(protocolSlash + numbersOrRange);
+    protoPortsCommas = paren(paren(protoPorts + "," + whitespace)+"+");
+    multiProtoPorts = paren(protoPortsCommas + protoPorts);
+    portSpec = "^" + paren(protoPorts + "|" + multiProtoPorts) + "$";
+    return RegExp(portSpec);
+}
+
+function portlist_selftest() {
+    r = portlist_regexp();
+    assert(! "tcp".match(r), 'should not have matched: "tcp"');
+    assert("tcp 1".match(r), 'should have matched: "tcp 1"');
+    assert("tcp 123".match(r), 'should have matched: "tcp 123"');
+    assert("tcp  123".match(r), 'should have matched: "tcp 123"');
+    assert("tcp 123-456".match(r), 'should have matched: "tcp 123-456"');
+    assert("tcp 123:456".match(r), 'should have matched: "tcp 123:456"');
+    assert(! "tcp 123-".match(r), 'should have matched: "tcp 123-"');
+    assert(! "tcp 123:".match(r), 'should have matched: "tcp 123:"');
+    assert(! "foo 123".match(r), 'should not have matched "foo 123"');
+    assert("udp 123".match(r), 'should have matched: "udp 123"');
+    assert("tcp 123,udp 456".match(r), 'should have matched: "tcp 123,udp 456"');
+    assert("tcp 123, udp 456".match(r), 'should have matched: "tcp 123, udp 456"');
+    assert("tcp 123,  udp 456".match(r), 'should have matched: "tcp 123,  udp 456"');
+    assert("tcp 123-45, udp 456".match(r), 'should have matched: "tcp 123-45, udp 456"');
+    assert("tcp 123-45, udp 456, tcp 11, tcp 22:45, udp 76, udp 47:49, udp 60-61".match(r), 'should have matched: "tcp 123-45, udp 456, tcp 11, tcp 22:45, udp 76, udp 47:49, udp 60-61"');
+    return "done";
+}
+
+//portlist_selftest();
+
+