001: /* Copyright 2006 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.security.provider.cas;
007:
008: import java.util.ArrayList;
009: import java.util.List;
010:
011: import org.jasig.portal.ChannelRuntimeData;
012: import org.jasig.portal.ChannelStaticData;
013: import org.jasig.portal.security.provider.BrokenSecurityContext;
014: import org.jasig.portal.security.provider.PersonImpl;
015:
016: import junit.framework.TestCase;
017:
018: /**
019: * JUnit testcase exercising CasConnectionContext.
020: */
021: public class CasConnectionContextTest extends TestCase {
022:
023: /**
024: * Test that when no ICasSecurityContext is present,
025: * the CasConnectionContext does not modify descriptors.
026: */
027: public void testNoCasSecurityContextPresent() {
028:
029: PersonImpl person = new PersonImpl();
030: // not a CAS security context
031: BrokenSecurityContext brokenContext = new BrokenSecurityContext();
032:
033: person.setSecurityContext(brokenContext);
034:
035: ChannelStaticData staticData = new ChannelStaticData();
036: staticData.setPerson(person);
037:
038: CasConnectionContext connectionContext = new CasConnectionContext();
039: connectionContext.init(staticData);
040:
041: String service = "http://www.someschool.edu/someservice";
042:
043: // in absence of CAS security context, return descriptor unchanged
044: assertEquals(service, connectionContext.getDescriptor(service));
045:
046: ChannelRuntimeData runtimeData = new ChannelRuntimeData();
047: runtimeData.setHttpRequestMethod("GET");
048:
049: String descriptorWithRuntimeData = connectionContext
050: .getDescriptor(service, runtimeData);
051:
052: // in absence of CAS security context, return descriptor unchanged.
053: assertEquals(service, descriptorWithRuntimeData);
054:
055: runtimeData.setHttpRequestMethod("POST");
056:
057: // when method is POST, return descriptor unchanged
058: descriptorWithRuntimeData = connectionContext.getDescriptor(
059: service, runtimeData);
060:
061: assertEquals(service, descriptorWithRuntimeData);
062:
063: }
064:
065: /**
066: * When an ICasSecurityContext is present but unauthenticated,
067: * CasConnectionContext will ignore it.
068: */
069: public void testUnauthenticatedCasSecurityContext() {
070: PersonImpl person = new PersonImpl();
071: // a CAS security context
072: CasSecurityContextMock mockCasContext = new CasSecurityContextMock();
073: mockCasContext.setAuthenticated(false);
074:
075: person.setSecurityContext(mockCasContext);
076:
077: ChannelStaticData staticData = new ChannelStaticData();
078: staticData.setPerson(person);
079:
080: CasConnectionContext connectionContext = new CasConnectionContext();
081: connectionContext.init(staticData);
082:
083: String service = "http://www.someschool.edu/someservice";
084:
085: // in absence of authenticated CAS security context, return descriptor unchanged
086: assertEquals(service, connectionContext.getDescriptor(service));
087:
088: ChannelRuntimeData runtimeData = new ChannelRuntimeData();
089: runtimeData.setHttpRequestMethod("GET");
090:
091: String descriptorWithRuntimeData = connectionContext
092: .getDescriptor(service, runtimeData);
093:
094: // in absence of authenticated CAS security context, return descriptor unchanged.
095: assertEquals(service, descriptorWithRuntimeData);
096:
097: runtimeData.setHttpRequestMethod("POST");
098:
099: // when method is POST, return descriptor unchanged
100: descriptorWithRuntimeData = connectionContext.getDescriptor(
101: service, runtimeData);
102:
103: assertEquals(service, descriptorWithRuntimeData);
104: }
105:
106: /**
107: * When an ICasSecurityContext is present, CasConnectionContext will
108: * use the ICasSecurityContext as a source of proxy tickets
109: */
110: public void testCasSecurityContext() {
111: PersonImpl person = new PersonImpl();
112: // a CAS security context
113: CasSecurityContextMock mockCasContext = new CasSecurityContextMock();
114: mockCasContext.setAuthenticated(true);
115:
116: List proxyTickets = new ArrayList();
117: proxyTickets.add("proxyTicket1");
118: proxyTickets.add("proxyTicket2");
119: proxyTickets.add("proxyTicket3");
120:
121: mockCasContext.setServiceTokensToVend(proxyTickets);
122:
123: person.setSecurityContext(mockCasContext);
124:
125: ChannelStaticData staticData = new ChannelStaticData();
126: staticData.setPerson(person);
127:
128: CasConnectionContext connectionContext = new CasConnectionContext();
129: connectionContext.init(staticData);
130:
131: String serviceOne = "http://www.someschool.edu/someservice";
132: String expectedResponse = "http://www.someschool.edu/someservice?ticket=proxyTicket1";
133:
134: // the connection context should append the ticket from the security context
135: assertEquals(expectedResponse, connectionContext
136: .getDescriptor(serviceOne));
137:
138: // the descriptor presented to the cas security context was the service.
139: assertEquals(serviceOne, (String) mockCasContext
140: .getServiceTokenTargets().get(0));
141:
142: ChannelRuntimeData runtimeData = new ChannelRuntimeData();
143: runtimeData.setHttpRequestMethod("GET");
144:
145: String serviceTwo = "https://www.ja-sig.org/somepath?queryParamsPresent=true";
146: String expectedResponseTwo = "https://www.ja-sig.org/somepath?queryParamsPresent=true&ticket=proxyTicket2";
147: String descriptorWithRuntimeData = connectionContext
148: .getDescriptor(serviceTwo, runtimeData);
149:
150: // the connection context should properly append the ticket parameter with an ampersand
151: assertEquals(expectedResponseTwo, descriptorWithRuntimeData);
152:
153: }
154:
155: /**
156: * When the Http request method is post,
157: * CasConnectionContext returns the descriptor unaltered.
158: */
159: public void testPostCasSecurityContext() {
160: PersonImpl person = new PersonImpl();
161: // a CAS security context
162: CasSecurityContextMock mockCasContext = new CasSecurityContextMock();
163: mockCasContext.setAuthenticated(true);
164:
165: List proxyTickets = new ArrayList();
166: proxyTickets.add("proxyTicket1");
167: proxyTickets.add("proxyTicket2");
168: proxyTickets.add("proxyTicket3");
169:
170: mockCasContext.setServiceTokensToVend(proxyTickets);
171:
172: person.setSecurityContext(mockCasContext);
173:
174: ChannelStaticData staticData = new ChannelStaticData();
175: staticData.setPerson(person);
176:
177: CasConnectionContext connectionContext = new CasConnectionContext();
178: connectionContext.init(staticData);
179:
180: String serviceOne = "http://www.uportal.org/someservice";
181:
182: ChannelRuntimeData runtimeData = new ChannelRuntimeData();
183:
184: runtimeData.setHttpRequestMethod("POST");
185:
186: // when method is POST, return descriptor unchanged
187: String descriptorWithRuntimeData = connectionContext
188: .getDescriptor(serviceOne, runtimeData);
189:
190: assertEquals(serviceOne, descriptorWithRuntimeData);
191: }
192:
193: /**
194: * The CasConnectionContext behaves slightly differently when
195: * a particular ChannelStaticData parameter "upc_cas_service_uri" is
196: * present. When present,
197: * this static parameter identifies the service, rather than
198: * the descriptors passed at runtime, for the getDescriptor(String descriptor)
199: * method (but not for the method that takes the ChannelRuntimeData
200: * as an argument). This affects what service the
201: * CasConnectionContext passes to the ICasSecurityContext for acquisition
202: * of a proxy ticket, but it *does not* change the descriptor the
203: * CasConnectionContext uses to compose the modified descriptor it returns.
204: */
205: public void testStaticData() {
206: PersonImpl person = new PersonImpl();
207: // a CAS security context
208: CasSecurityContextMock mockCasContext = new CasSecurityContextMock();
209: mockCasContext.setAuthenticated(true);
210:
211: List proxyTickets = new ArrayList();
212: proxyTickets.add("proxyTicket1");
213: proxyTickets.add("proxyTicket2");
214: proxyTickets.add("proxyTicket3");
215: proxyTickets.add("proxyTicket4");
216:
217: mockCasContext.setServiceTokensToVend(proxyTickets);
218:
219: person.setSecurityContext(mockCasContext);
220:
221: ChannelStaticData staticData = new ChannelStaticData();
222: staticData.setPerson(person);
223: String staticallyDefinedUri = "https://statically.defined.uri.com/";
224: staticData.setParameter("upc_cas_service_uri",
225: staticallyDefinedUri);
226:
227: CasConnectionContext connectionContext = new CasConnectionContext();
228: connectionContext.init(staticData);
229:
230: String serviceOne = "http://www.someschool.edu/someservice";
231: String expectedResponse = "http://www.someschool.edu/someservice?ticket=proxyTicket1";
232:
233: // the connection context should append the ticket from the security context
234: assertEquals(expectedResponse, connectionContext
235: .getDescriptor(serviceOne));
236:
237: // the descriptor presented to the cas security context was the statically defined URI.
238: assertEquals(staticallyDefinedUri, (String) mockCasContext
239: .getServiceTokenTargets().get(0));
240:
241: ChannelRuntimeData runtimeData = new ChannelRuntimeData();
242: runtimeData.setHttpRequestMethod("GET");
243:
244: String serviceTwo = "https://www.ja-sig.org/somepath?queryParamsPresent=true";
245: String expectedResponseTwo = "https://www.ja-sig.org/somepath?queryParamsPresent=true&ticket=proxyTicket2";
246: String descriptorWithRuntimeData = connectionContext
247: .getDescriptor(serviceTwo, runtimeData);
248:
249: // the connection context should properly append the ticket parameter with an ampersand
250: assertEquals(expectedResponseTwo, descriptorWithRuntimeData);
251:
252: // the descriptor presented to the cas security context was the uri presented on the
253: // method call -- the method that takes the ChannelRuntimeData as an argument
254: // does not honor the upc_cas_service_url ChannelStaticData parameter.
255: assertEquals(serviceTwo, (String) mockCasContext
256: .getServiceTokenTargets().get(1));
257:
258: String expectedResponseThree = "proxyTicket3";
259:
260: // even if the runtime descriptor is null, responds with the channel static data configured
261: // descriptor
262: assertEquals(expectedResponseThree, connectionContext
263: .getDescriptor(null, runtimeData));
264:
265: // the descriptor presented to the cas security context was the null passed in
266: assertEquals(null, (String) mockCasContext
267: .getServiceTokenTargets().get(2));
268:
269: }
270:
271: /**
272: * CasConnectionContext offers a getPostData() method used which reads
273: * a specific parameter from ChannelRuntimeData (cw_xml) and returns the
274: * parameter name=value pair for presenting a proxy ticket to that URL. When
275: * that parameter is not present, it reads a parameter from ChannelStaticData.
276: * When neither are present, it attempts to acquire a proxy ticket targetted
277: * at the null service.
278: */
279: public void testGetPostData() {
280:
281: PersonImpl person = new PersonImpl();
282: // a CAS security context
283: CasSecurityContextMock mockCasContext = new CasSecurityContextMock();
284: mockCasContext.setAuthenticated(true);
285:
286: List proxyTickets = new ArrayList();
287: proxyTickets.add("proxyTicket1");
288: proxyTickets.add("proxyTicket2");
289: proxyTickets.add("proxyTicket3");
290: proxyTickets.add("proxyTicket4");
291:
292: mockCasContext.setServiceTokensToVend(proxyTickets);
293:
294: person.setSecurityContext(mockCasContext);
295:
296: ChannelStaticData staticData = new ChannelStaticData();
297: staticData.setPerson(person);
298:
299: CasConnectionContext connectionContext = new CasConnectionContext();
300: connectionContext.init(staticData);
301:
302: ChannelRuntimeData withoutParameter = new ChannelRuntimeData();
303:
304: // when the "cw_xml" parameter is neither present in ChannelRuntimeData nor
305: // in ChannelStaticData, the CasConnectionContext acquires a ticket for the
306: // null service
307: assertEquals("ticket=proxyTicket1", connectionContext
308: .getPostData(withoutParameter));
309: assertEquals(null, mockCasContext.getServiceTokenTargets().get(
310: 0));
311:
312: ChannelRuntimeData withParameter = new ChannelRuntimeData();
313: String runtimeService = "http://baseactionurl.blogspot.com/2005/12/ja-sig-facebook.html";
314: withParameter.setParameter("cw_xml", runtimeService);
315:
316: // read the cw_xml parameter from ChannelRuntimeData
317: assertEquals("ticket=proxyTicket2", connectionContext
318: .getPostData(withParameter));
319: assertEquals(runtimeService, mockCasContext
320: .getServiceTokenTargets().get(1));
321:
322: // prefer the parameter from ChannelRuntimeData rather than ChannelStaticData
323: ChannelStaticData staticDataWithUri = new ChannelStaticData();
324: staticDataWithUri.setPerson(person);
325: String staticService = "http://www.ja-sig.org/wiki/";
326: staticDataWithUri.setParameter("cw_xml", staticService);
327:
328: connectionContext.init(staticDataWithUri);
329:
330: assertEquals("ticket=proxyTicket3", connectionContext
331: .getPostData(withParameter));
332: assertEquals(runtimeService, mockCasContext
333: .getServiceTokenTargets().get(2));
334:
335: // fall back on the parameter in ChannelStaticData when not present in runtime data
336: assertEquals("ticket=proxyTicket4", connectionContext
337: .getPostData(withoutParameter));
338: assertEquals(staticService, mockCasContext
339: .getServiceTokenTargets().get(3));
340: }
341:
342: }
|