Application Delivery Management
Application Modernization & Connectivity
CyberRes by OpenText
IT Operations Management
<%--
SOP Circumnavigator
Copyright (C) 2015 Robert Rawson (for CIS, LLC)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
CIS may be contacted by eMail at service@cisus.com, by phone at (212) 577-6033 or by
US Mail at 561 Seventh Ave, 13th Floor, New York, NY 10018
- - -
With due respect to the late Douglas Adams, SOP is not "Somebody Else's Problem"
This file is intended to circumvent the browser SOP (Same Origin Policy) in order to allow a
query to IDM from a browser form, specifically built for NetIQ's form engine. It depends on
a remote loader on the same server as UA set to listen on port 60609 connecting to a specially
configured SOAP driver.
To deploy this code, place this jsp file in the ROOT.war, and copy the file commons-httpclient-3.1.jar to
the ROOT.war/WEB-INF/lib directory. A web server restart may be required.
--%>
<%@page import="java.io.StringWriter"%>
<%@page language="java"
contentType="application/json;"
pageEncoding="ISO-8859-1"
import="java.net.*"%>
<%@page import="java.io.*"%>
<%@page import="java.util.*"%>
<%@page import="org.apache.commons.httpclient.*"%>
<%@page import="org.apache.commons.httpclient.methods.*"%>
<%
BufferedReader in = request.getReader();
String XML = "";
String line = null;
while((line = in.readLine()) != null) {
XML = XML line "\n";
}
try
{
// read data sent from the client
String strURL = "http://127.0.0.1:60609/";
PostMethod post = new PostMethod(strURL);
try
{
System.out.println("[CIS]: Making request to SOAP driver");
System.out.println(XML);
StringRequestEntity requestEntity = new StringRequestEntity(XML);
post.setRequestEntity(requestEntity);
post.setRequestHeader("Content-type","text/xml; charset=UTF-8");
HttpClient httpclient = new HttpClient();
int result = httpclient.executeMethod(post);
System.out.println("[CIS] Received response code from SOAP driver: " Integer.toString(result));
System.out.println(post.getResponseBodyAsString());
PrintWriter writer = response.getWriter();
writer.println(post.getResponseBodyAsString());
response.flushBuffer();
}
catch ( Exception e )
{
System.out.print( "[CIS] e=" e.toString() );
out.write( "{[ " e.toString() " ]}" );
}
finally
{
post.releaseConnection();
}
}
catch (IOException e)
{
e.printStackTrace();
}
%>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE policy PUBLIC "policy-builder-dtd" "/home/rrawson/designer/plugins/com.novell.idm.policybuilder_4.0.0.201410091552/DTD/dirxmlscript4.0.2.dtd"><policy>
<rule>
<description>[CIS] tag query dox</description>
<conditions>
<and>
<if-operation mode="nocase" op="equal">query</if-operation>
<if-xml-attr name="dest-driver-dn" op="available"/>
</and>
</conditions>
<actions>
<do-set-op-property name="orig-query">
<arg-string>
<token-time format="!JTIME" tz="UTC"/>
</arg-string>
</do-set-op-property>
<do-clone-xpath dest-expression="operation-data" src-expression="."/>
</actions>
</rule>
</policy>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE policy PUBLIC "policy-builder-dtd" "/home/rrawson/designer/plugins/com.novell.idm.policybuilder_4.0.0.201410091552/DTD/dirxmlscript4.0.2.dtd"><policy xmlns:dircmd="http://www.novell.com/nxsl/java/com.novell.nds.dirxml.driver.cmd.DriverCmd">
<rule>
<description>[CIS] Tag instance doc from engine</description>
<conditions>
<and>
<if-operation mode="nocase" op="equal">instance</if-operation>
<if-op-property name="orig-query" op="available"/>
</and>
</conditions>
<actions>
<do-set-xml-attr expression="." name="from-driver-dn">
<arg-string>
<token-global-variable name="dirxml.auto.driverdn"/>
</arg-string>
</do-set-xml-attr>
<do-strip-xpath expression="/nds/output/status"/>
</actions>
</rule>
<rule>
<description>[CIS] Separate dest-driver-dn from incoming XDS</description>
<conditions>
<and>
<if-operation mode="nocase" op="equal">status</if-operation>
<if-op-property name="orig-query" op="available"/>
</and>
</conditions>
<actions>
<do-set-local-variable name="xds-query" scope="policy">
<arg-node-set>
<token-xml-parse>
<token-text xml:space="preserve"><nds><input/></nds></token-text>
</token-xml-parse>
</arg-node-set>
</do-set-local-variable>
<do-clone-xpath dest-expression="$xds-query/nds/input" src-expression="operation-data/query"/>
<do-set-local-variable name="dest-driver-dn" scope="policy">
<arg-string>
<token-xpath expression="$xds-query/nds/input/query/@dest-driver-dn"/>
</arg-string>
</do-set-local-variable>
<do-strip-xpath expression="$xds-query/nds/input/query/@dest-driver-dn"/>
<do-set-local-variable name="Q" scope="policy">
<arg-node-set>
<token-xpath expression="dircmd:sendDriverCommand($dest-driver-dn, $xds-query/nds)"/>
</arg-node-set>
</do-set-local-variable>
<do-set-xml-attr expression="$Q//instance" name="from-driver-dn">
<arg-string>
<token-local-variable name="dest-driver-dn"/>
</arg-string>
</do-set-xml-attr>
<do-strip-xpath expression="/nds/*"/>
<do-append-xml-element expression="/nds" name="output"/>
<do-clone-xpath dest-expression="/nds/output" src-expression="$Q//output"/>
</actions>
</rule>
</policy>
/** enable XML support **/
function createXMLHttpRequest() {
try { return new XMLHttpRequest(); } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
form.alert("XMLHttpRequest not supported by this browser");
return null;
}
xmlhttp = createXMLHttpRequest();
function xmlParse(XML)
{
var oParser = new DOMParser();
var oDOM = oParser.parseFromString(XML, "text/xml");
return oDOM;
}
function xmlSetText(DOM, elementName, value)
{
var textNode = DOM.getElementsByTagName("value")[0].childNodes[0]
textNode.nodeValue = value;
}
function xmlSetAttribute(DOM, elementName, attributeName, value)
{
var attrNode = DOM.getElementsByTagName(elementName)[0].getAttributeNode(attributeName);
attrNode.nodeValue = value;
}
function getXMLResponse(form,field,xmlhttp,url,domRequest,callbackFunction)
{
txtRequest = new XMLSerializer().serializeToString(domRequest.documentElement);
xmlhttp.open("POST",url,true);
xmlhttp.setRequestHeader("Content-type", "text/xml");
xmlhttp.send(txtRequest);
xmlhttp.onreadystatechange= callbackFunction;
}
function xmlGetText(DOM, elementName)
{
var textNode = DOM.getElementsByTagName("value")[0].childNodes[0]
return textNode.nodeValue;
}
function xmlGetAttribute(DOM, elementName, attributeName)
{
var attrNode = DOM.getElementsByTagName(elementName)[0].getAttributeNode(attributeName);
return attrNode.nodeValue;
}
function ndap2ldap(ndapName)
{
var parts = ndapName.split("\\");
var ldapName = "";
for (var i = 0; i < parts.length; i )
{
ldapName = parts[i] "," ldapName;
}
return ldapName.substring(0,ldapName.length-1);
}
function xmlGetElementByAttribute(DOM, elementName, attributeName, value)
{
var textNodes = DOM.getElementsByTagName(elementName)
//Form.showDebugMsg("Found " textNodes.length.toString() " GCVs")
for (var i = 0; i < textNodes.length; i )
{
var attrNode = textNodes[i].getAttributeNode(attributeName);
if (attrNode.nodeValue == value)
{
return textNodes[i]
}
}
return "";
}
// Functions specific to this workflow
function queryDoc()
{
var XML = "<query dest-driver-dn='{driverDN}' class-name='User' event-id='0' scope='subtree'>"
XML =" <search-class class-name='User'/>"
XML =" <search-attr attr-name='{searchAttr}'>"
XML =" <value>{userName}</value>"
XML =" </search-attr>"
XML =" <read-attr attr-name='CN'/>"
XML =" <read-attr attr-name='Full Name'/>"
XML =" <read-attr attr-name='Given Name'/>"
XML =" <read-attr attr-name='Surname'/>"
XML =" <read-attr attr-name='acmeASDaccountId'/>"
XML =" <read-attr attr-name='acmeAUVloginId'/>"
XML =" <read-attr attr-name='acmeAHCloginId'/>"
XML =" <read-attr attr-name='acmeASDsuppressInfo'/>"
XML =" </query>";
return XML;
}
driverName="\\ASD JDBC"
driverSet="\\ACMEDEV\\AcmeDev\\Servers\\DRIVERSET01"
//this function fires when the response is returned. It fires an event which starts with onresponse-
function OnStateChange() {
if (xmlhttp.readyState==4) {
field.fireEvent("onresponse-" field.getName(),xmlhttp.responseText)
}
}
function userExists(attributeName, value)
{
var domRequest = xmlParse(queryDoc());
xmlSetAttribute(domRequest, "query", "dest-driver-dn", driverSet driverName);
xmlSetAttribute(domRequest, "search-attr", "attr-name", attributeName)
xmlSetText(domRequest, "value", value)
getXMLResponse(form,field,xmlhttp,"/queryNDAP.jsp",domRequest, OnStateChange);
}
hideSubmit();
form.clearMessages();
field.setValues("0","Searching, please wait...", false);
field.show();
field.fireEvent("onSearchStart");
var num = '-1';
var attr = form.getValue("queryAttr");
var result = '';
var fullName = '';
var ppid = '';
var num = 0;
var searchValue = form.getValue("queryVal");
if (searchValue != "")
{
form.clearMessages();
if (attr=="CN") searchValue=searchValue.toUpperCase()
userExists(attr,searchValue)
}
else
{
form.showError("Search value cannot be blank.")
}
function ud(va)
{
if (undef(va))
{return "(unvalued)"}
else
{return va}
}
ldapUserContainer = "OU=Users,OU=Data,O=AcmeDev";
driverName="\\ASD JDBC"
driverSet="\\ACMEDEV\\AcmeDev\\Servers\\DRIVERSET01"
var queryResponse = new Array()
var domResponse = xmlParse(event.getCustomData());
var instances = domResponse.getElementsByTagName("instance")
var attrs = domResponse.getElementsByTagName("attr")
var num = instances.length;
if (instances.length.toString() > 0 )
{
queryResponse["from-driver-dn"] = xmlGetAttribute(domResponse,"instance","from-driver-dn");
queryResponse["src-dn"] = xmlGetAttribute(domResponse,"instance","src-dn");
if (queryResponse["from-driver-dn"].toLowerCase() != driverSet.toLowerCase() driverName.toLowerCase())
{
queryResponse["qualified-src-dn"] = xmlGetAttribute(domResponse,"instance","qualified-src-dn");
queryResponse["ldap-dn"] = ndap2ldap(queryResponse["qualified-src-dn"] );
}
for (var i=0; i < attrs.length; i )
{
var attr = attrs.item(i);
var attrName = attr.getAttributeNode("attr-name").value;
var value = attr.getElementsByTagName("value")[0].textContent.toString(); z
queryResponse[attrName] = value;
form.setValues(vacuum(attrName), value)
}
}
else
{
queryResponse["from-driver-dn"] = "NOT FOUND"
}
if (queryResponse["from-driver-dn"] == "NOT FOUND")
{
form.showError("No user found")
}
else
{
var subHead = "Existing";
if (queryResponse["from-driver-dn"].toLowerCase() != driverSet.toLowerCase() driverName.toLowerCase()) //found in VAULT
{
field.setValues(queryResponse["ldap-dn"], queryResponse["Full Name"], false);
}
else // found in ASD
{
var newObjectDN="CN=" queryResponse["CN"] "," ldapUserContainer;
subHead = "New"
field.setValues(newObjectDN, queryResponse["Full Name"], false);
field.fireEvent("NeedsPassword");
}
field.fireEvent("onValidQueryResultsValue()",queryResponse);
var Head = "Create User"
var nbsp=" ";
var sep = nbsp "|" nbsp;
var br = "<br/>\n";
var b1 = "<b>";
var b0 = "</b>";
var rowstart= "<tr><td>";
var rowend= "</td></tr>";
html = "<table>"
html= html rowstart "<h3>" Head " - " ud(queryResponse["Full Name"]) " (" ud(queryResponse["CN"]) ")</h3></td><tr>" rowend;
html = html rowstart "<h4>" subHead " user:</h4>" rowend;
html = html rowstart b1 "Last Name:" b0 nbsp queryResponse["Surname"] sep b1 "First Name:" b0 nbsp ud(queryResponse["Given Name"]) sep b1 "Info (FERPA) Suppress?" b0 nbsp ud(queryResponse["AcmeASDsuppressInfo"]) rowend;
html = html rowstart b1 "Public Person Id:" b0 nbsp queryResponse["CN"] sep b1 "AUV Login Id:" b0 nbsp ud(queryResponse["AcmeEUVloginId"]) sep b1 "ACH Login Id:" b0 nbsp ud(queryResponse["ACH Login Id"]) sep b1 "Person Number:" b0 nbsp ud(queryResponse["AcmeASDaccountId"]) rowend;
html = html "</table>"
field.fireEvent("htmlready-" field.getName(),html)
}
field.select();
field.hide();