1 /* zxidappdemo.java  -  Demonstrate detecting missing session and redirection to zxidsrvlet
2  * Copyright (c) 2010 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.
3  * Copyright (c) 2009 Symlabs (symlabs@symlabs.com), All Rights Reserved.
4  * Author: Sampo Kellomaki (sampo@iki.fi)
5  * This is confidential unpublished proprietary source code of the author.
6  * NO WARRANTY, not even implied warranties. Contains trade secrets.
7  * Distribution prohibited unless authorized in writing.
8  * Licensed under Apache License 2.0, see file COPYING.
9  * $Id: zxidappdemo.java,v 1.4 2009-11-29 12:23:06 sampo Exp $
10  * 16.10.2009, created --Sampo
11  *
12  * This servlet plays the role of "payload" servlet in ZXID SSO servlet
13  * integration demonstration. It illustrates the steps
14  * 1.  Detect that there is no session and redirect to zxidsrvlet; and
15  * 7.  Access to protected resource, with attributes already populated
16  *     to the HttpSession (JSESSION)
17  * 9.  Making a web service call by directly calling zxid_call()
18  *
19  * See also: zxid-java.pd, zxidwspdemo.java for server side
20  */
21 
22 import zxidjava.*;   // Pull in the zxidjni.az() API
23 import java.io.*;
24 import javax.servlet.*;
25 import javax.servlet.http.*;
26 import java.util.regex.Pattern;
27 import java.util.regex.Matcher;
28 import java.util.Enumeration;
29 
30 public class zxidappdemo extends HttpServlet {
31     static final boolean verbose = false;
32     static final Pattern fedusername_pat = Pattern.compile("fedusername:[ ]([^\\n]*)");
33     static final Pattern idpnid_pat = Pattern.compile("idpnid:[ ]([^\\n]*)");
34     static final Pattern nidfmt_pat = Pattern.compile("nidfmt:[ ]([^\\n]*)");
35     static final Pattern affid_pat  = Pattern.compile("affid:[ ]([^\\n]*)");
36     static final Pattern eid_pat    = Pattern.compile("eid:[ ]([^\\n]*)");
37     static final Pattern cn_pat     = Pattern.compile("cn:[ ]([^\\n]*)");
38     static final Pattern o_pat      = Pattern.compile("o:[ ]([^\\n]*)");
39     static final Pattern ou_pat     = Pattern.compile("ou:[ ]([^\\n]*)");
40     static final Pattern role_pat   = Pattern.compile("role:[ ]([^\\n]*)");
41     static final Pattern boot_pat   = Pattern.compile("urn:liberty:disco:2006-08:DiscoveryEPR:[ ]([^\\n]*)");
42 
43     static final String conf = "URL=http://sp1.zxidsp.org:8080/sso&CPATH=/var/zxid/";
44     static zxidjava.zxid_conf cf;
45     static {
46 	// CONFIG: You must have created /var/zxid directory hierarchy. See `make dir'
47 	// CONFIG: You must create edit the URL to match your domain name and port
48 	// CONFIG: Usually you create and edit /var/zxid/zxid.conf and override the URL there
49 
50 	//System.out.println(System.getProperty("java.version"));
51 	//System.out.println(System.getProperty("java.vm.version"));
52 	//System.out.println(System.getProperty("java.class.version"));
53 	//System.out.println(System.getProperty("java.class.path"));
54 	//System.out.println(System.getProperty("java.library.path"));
55 
56 	System.loadLibrary("zxidjni");
57 	cf = zxidjni.new_conf_to_cf(conf);
zxidjni.set_opt(cf, 1, 1)58 	zxidjni.set_opt(cf, 1, 1);
59     }
60 
hilite_fields(ServletOutputStream out, String ret, int n)61     public void hilite_fields(ServletOutputStream out, String ret, int n)
62 	throws IOException
63     {
64 	int i;
65 	try {
66 	    Matcher matcher = idpnid_pat.matcher(ret);
67 	    for (i = n; i > 0; --i)
68 		matcher.find();
69 	    out.print("<b>fedusername</b>: " + matcher.group(1) + "<br>\n");
70 	} catch(IllegalStateException e) { }
71 
72 	try {
73 	    Matcher matcher = idpnid_pat.matcher(ret);
74 	    for (i = n; i > 0; --i)
75 		matcher.find();
76 	    out.print("<b>idpnid</b>: " + matcher.group(1) + "<br>\n");
77 	} catch(IllegalStateException e) { }
78 
79 	try {
80 	    Matcher matcher2 = nidfmt_pat.matcher(ret);
81 	    for (i = n; i > 0; --i)
82 		matcher2.find();
83 	    out.print("<b>nidfmt</b>: " + matcher2.group(1) + "<br>\n");
84 	} catch(IllegalStateException e) { }
85 
86 	try {
87 	    Matcher matcher3 = affid_pat.matcher(ret);
88 	    for (i = n; i > 0; --i)
89 		matcher3.find();
90 	    out.print("<b>affid</b>: " + matcher3.group(1) + "<br>\n");
91 	} catch(IllegalStateException e) { }
92 
93 	try {
94 	    Matcher matcher = eid_pat.matcher(ret);
95 	    for (i = n; i > 0; --i)
96 		matcher.find();
97 	    out.print("<b>eid</b>: " + matcher.group(1) + "<br>\n");
98 	} catch(IllegalStateException e) { }
99 
100 	try {
101 	    Matcher matcher = cn_pat.matcher(ret);
102 	    for (i = n; i > 0; --i)
103 		matcher.find();
104 	    out.print("<b>cn</b>: " + matcher.group(1) + "<br>\n");
105 	} catch(IllegalStateException e) { }
106 
107 	try {
108 	    Matcher matcher = o_pat.matcher(ret);
109 	    for (i = n; i > 0; --i)
110 		matcher.find();
111 	    out.print("<b>o</b>: " + matcher.group(1) + "<br>\n");
112 	} catch(IllegalStateException e) { }
113 
114 	try {
115 	    Matcher matcher = ou_pat.matcher(ret);
116 	    for (i = n; i > 0; --i)
117 		matcher.find();
118 	    out.print("<b>ou</b>: " + matcher.group(1) + "<br>\n");
119 	} catch(IllegalStateException e) { }
120 
121 	try {
122 	    Matcher matcher = role_pat.matcher(ret);
123 	    for (i = n; i > 0; --i)
124 		matcher.find();
125 	    out.print("<b>role</b>: " + matcher.group(1) + "<br>\n");
126 	} catch(IllegalStateException e) { }
127 
128 	try {
129 	    Matcher matcher = boot_pat.matcher(ret);
130 	    for (i = n; i > 0; --i)
131 		matcher.find();
132 	    out.print("<b>urn:liberty:disco:2006-08:DiscoveryEPR</b>: " + matcher.group(1) + "<br>\n");
133 	} catch(IllegalStateException e) { }
134 
135     }
136 
doGet(HttpServletRequest req, HttpServletResponse res)137     public void doGet(HttpServletRequest req, HttpServletResponse res)
138 	throws ServletException, IOException
139     {
140 	String fullURL = req.getRequestURI();
141 	String qs = req.getQueryString();
142 	if (qs != null)
143 	    fullURL += "?" + req.getQueryString();
144 	else
145 	    qs = "";
146 	System.err.print("Start ZXID App Demo GET("+fullURL+")...\n");
147 	HttpSession ses = req.getSession(false);  // Important: do not allow automatic session.
148 	if (ses == null) {                        // Instead, redirect to sso servlet.
149 	    res.sendRedirect("sso?o=E&fr=" + fullURL);
150 	    return;
151 	}
152 	ServletOutputStream out = res.getOutputStream();
153 
154 	res.setContentType("text/html");
155 	out.print("<title>ZXID Demo App Protected Content</title><body>\n");
156 	out.print("<table align=right><tr><td>");
157 	out.print("<a href=\"http://www.tas3.eu/\"><img src=\"tas3-logo.jpg\" height=64 border=0></a>");
158 	out.print("<a href=\"http://zxid.org/\"><img src=\"logo-zxid-128x128.png\" height=64 border=0></a>");
159 	out.print("</td></tr></table>");
160 	out.print("<h1>ZXID Demo App Protected Content</h1>\n");
161 	//out.print("<h1>ZXID Demo App Protected Content</h1> at " + fullURL + "\n");
162 
163 	// Render logout buttons (optional)
164 
165 	out.print("[<a href=\"sso?gl=1&s="+ses.getAttribute("sesid")+"\">Local Logout</a> | <a href=\"sso?gr=1&s="+ses.getAttribute("sesid")+"\">Single Logout</a>]\n");
166 
167 	// The SSO servlet will have done one iteration of authorization. The following
168 	// serves to illustrate, how to explicitly call a PDP from your code.
169 
170 	if (zxidjni.az_cf(cf, "Action=Show", ses.getAttribute("sesid").toString()) == null) {
171 	    out.print("<p><b>Denied.</b> Normally page would not be shown, but we show the session attributes for debugging purposes.\n");
172 	    //res.setStatus(302, "Denied");
173 	} else {
174 	    out.print("<p>Authorized.\n");
175 	}
176 
177 	out.print("<table align=right><tr><td>");
178 	out.print("<img src=\"tas3-recurs-demo.png\" width=500 border=0>");
179 	out.print("</td></tr></table>");
180 
181 	// Render protected content page (your application starts working)
182 
183 	out.print("<h4>HttpSession dump:</h4>");
184 	Enumeration val_names = ses.getAttributeNames();
185 	while (val_names.hasMoreElements()) {
186 	    String name = (String)val_names.nextElement();
187 	    if (name.equals("cn")
188 		|| name.equals("role")
189 		|| name.equals("o")
190 		|| name.equals("ou")
191 		|| name.equals("idpnid")
192 		|| name.equals("nidfmt")
193 		|| name.equals("affid")
194 		|| name.equals("eid")
195 		|| name.equals("urn:liberty:disco:2006-08:DiscoveryEPR")) {
196 		out.print("<b>" + name + "</b>: " + ses.getAttribute(name) + "<br>\n");
197 	    } else {
198 		if (verbose)
199 		    out.print(name + ": " + ses.getAttribute(name) + "<br>\n");
200 	    }
201 	}
202 	out.print("<p>");
203 	out.print("[ <a href=\"?idhrxml\">tas3_call(idhrxml)</a>");
204 	out.print(" | <a href=\"?x-foobar\">Recursive Echo</a>");
205 	out.print(" | <a href=\"?leaf\">Leaf Echo</a>");
206 	out.print(" | <a href=\"?multidi\">Multi discovery</a>");
207 	out.print(" | <a href=\"?multi\">Multi discovery and call</a>");
208 	out.print(" | <a href=\"?all\">All</a>");
209 	out.print(" | <a href=\"?exit\">Exit Java</a>");
210 	out.print("]<p>");
211 
212 	// Demo web service call to zxidhrxmlwsp
213 
214 	String ret;
215 	String sid = ses.getAttribute("sesid").toString();
216 	zxid_ses zxses = zxidjni.fetch_ses(cf, sid);
217 
218 	if (qs.equals("idhrxml") || qs.equals("all")) {
219 	    out.print("<p>Output from idhrxml web service call sid("+sid+"):<br>\n<textarea cols=80 rows=20>");
220 	    ret = zxidjni.call(cf, zxses,
221 			       zxidjni.zx_xmlns_idhrxml,
222 			       "http://sp.tas3.pt:8081/zxidhrxmlwsp?o=B",
223 			       null, null,
224 			       "<idhrxml:Query>"
225 			       + "<idhrxml:QueryItem>"
226 			       + "<idhrxml:Select></idhrxml:Select>"
227 			       + "</idhrxml:QueryItem>" +
228 			       "</idhrxml:Query>");
229 
230 	    ret = zxidjni.extract_body(cf, ret);
231 	    out.print(ret);
232 	    out.print("</textarea>");
233 	}
234 
235 	// Demo another web service call, this time the service by zxidwspdemo.java
236 
237 	if (qs.equals("x-foobar") || qs.equals("all")) {
238 	    out.print("<p>Output from recursive web service call:<br>\n");
239 	    ret = zxidjni.call(cf, zxses, "urn:x-foobar",
240 			       "http://sp.tas3.pt:8080/zxidservlet/wspdemo?o=B", null, null,
241 			       "<foobar>Do it!</foobar>");
242 
243 	    ret = zxidjni.extract_body(cf, ret);
244 	    if (ret.indexOf("code=\"OK\"") == -1) {
245 		out.print("<p>Error from call:<br>\n<textarea cols=80 rows=20>");
246 		out.print(ret);
247 		out.print("</textarea>\n");
248 	    } else {
249 		out.print("<p>Output from Leaf web services call (relayed by middle call):<br>\n");
250 		hilite_fields(out, ret, 1);
251 		out.print("<p>Output from Middle web services call:<br>\n");
252 		hilite_fields(out, ret, 2);
253 		if (true || verbose) {
254 		    out.print("<textarea cols=80 rows=20>");
255 		    out.print(ret);
256 		    out.print("</textarea>\n");
257 		}
258 	    }
259 	}
260 
261 	// Demo another web service call, this time the service by zxidwspleaf.java
262 
263 	if (qs.equals("leaf") || qs.equals("all")) {
264 	    ret = zxidjni.call(cf, zxses, "x-recurs", null, null, null,
265 			       "<foobar>Do it!</foobar>");
266 
267 	    ret = zxidjni.extract_body(cf, ret);
268 	    if (ret.indexOf("code=\"OK\"") == -1) {
269 		out.print("<p>Error from call:<br>\n<textarea cols=80 rows=20>");
270 		out.print(ret);
271 		out.print("</textarea>\n");
272 	    } else {
273 		out.print("<p>Output from Leaf web services call:<br>\n");
274 		hilite_fields(out, ret, 1);
275 		if (true || verbose) {
276 		    out.print("<textarea cols=80 rows=20>");
277 		    out.print(ret);
278 		    out.print("</textarea>\n");
279 		}
280 	    }
281 	}
282 
283 	// Multidiscovery
284 
285 	if (qs.equals("multidi")) {
286 	    out.print("<h4>Multidiscovery</h4>\n");
287 
288 	    zxid_epr epr[] = new zxid_epr[100];
289 
290 	    for (int i=1; i<100; ++i) {
291 		epr[i] = zxidjni.get_epr(cf, zxses, "urn:x-foobar", null, null, null, i);
292 		if (epr[i] == null)
293 		    break;
294 		out.print("<p>EPR "+i+" <a href=\"?o=call&url="+zxidjni.get_epr_address(cf, epr[i])+"\">Call</a>");
295 		out.print(" desc("+zxidjni.get_epr_desc(cf, epr[i])+") svctype(urn:x-foobar)<br>\n");
296 		out.print(" address("+zxidjni.get_epr_address(cf, epr[i])+")<br>\n");
297 		out.print(" entid("+zxidjni.get_epr_entid(cf, epr[i])+")<br>\n");
298 	    }
299 	}
300 
301 	// Call specific
302 
303 	if (qs.startsWith("o=call&url=")) {
304 	    String url = qs.substring(11);
305 	    out.print("<h4>Specific Call</h4>\n");
306 	    ret = zxidjni.call(cf, zxses, "urn:x-foobar", url, null, null,
307 			       "<foobar>do it</foobar>");
308 	    ret = zxidjni.extract_body(cf, ret);
309 	    if (ret.indexOf("code=\"OK\"") == -1) {
310 		out.print("<p>Error from call address("+url+"):<br>\n<textarea cols=80 rows=20>");
311 		out.print(ret);
312 		out.print("</textarea>\n");
313 	    } else {
314 		out.print("<p>Output from call address("+url+"):<br>\n");
315 		hilite_fields(out, ret, 1);
316 		if (verbose) {
317 		    out.print("<textarea cols=80 rows=20>");
318 		    out.print(ret);
319 		    out.print("</textarea>\n");
320 		}
321 	    }
322 	}
323 
324 	// Multidiscovery and call
325 
326 	if (qs.equals("multi") || qs.equals("all")) {
327 	    out.print("<h4>Multidiscovery and Call</h4>\n");
328 
329 	    zxid_epr epr[] = new zxid_epr[100];
330 
331 	    for (int i=1; i<100; ++i) {
332 		epr[i] = zxidjni.get_epr(cf, zxses, "urn:x-foobar", null, null, null, i);
333 		if (epr[i] == null)
334 		    break;
335 		out.print("<p>EPR "+i+" address("+zxidjni.get_epr_address(cf, epr[i])+")\n");
336 		out.print("<p>EPR "+i+"   entid("+zxidjni.get_epr_entid(cf, epr[i])+")\n");
337 		out.print("<p>EPR "+i+"    desc("+zxidjni.get_epr_desc(cf, epr[i])+")\n");
338 	    }
339 
340 	    for (int i=1; i<100; ++i) {
341 		if (epr[i] == null)
342 		    break;
343 		out.print("<p>Output from multicall "+i+" entid:<br>\n<textarea cols=80 rows=20>");
344 		ret = zxidjni.call(cf, zxses, "urn:x-foobar", zxidjni.get_epr_entid(cf, epr[i]), null, null,
345 				   "<foobar>do i="+i+"</foobar>");
346 		ret = zxidjni.extract_body(cf, ret);
347 		out.print(ret);
348 		out.print("</textarea>\n");
349 
350 		out.print("<p>Output from multicall "+i+" address:<br>\n<textarea cols=80 rows=20>");
351 		ret = zxidjni.call(cf, zxses, "urn:x-foobar", zxidjni.get_epr_address(cf, epr[i]), null, null,
352 				   "<foobar>do i="+i+"</foobar>");
353 		ret = zxidjni.extract_body(cf, ret);
354 		out.print(ret);
355 		out.print("</textarea>\n");
356 	    }
357 	}
358 
359 	if (qs.equals("exit")) {
360 	    System.err.print("Controlled exit forced (can be used to cause __gcov_flush())\n");
361 	    zxidjni.set_opt(cf, 5, 0);
362 	}
363 
364 	out.print("<p>Done.\n");
365     }
366 }
367 
368 /* EOF */
369