001: /*
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: F_RunAs.java 6742 2005-05-12 14:39:55Z durieuxp $
023: * --------------------------------------------------------------------------
024: */
025:
026: package org.objectweb.jonas.jtests.clients.security;
027:
028: import javax.jms.Connection;
029: import javax.jms.ConnectionFactory;
030: import javax.jms.Destination;
031: import javax.jms.JMSException;
032: import javax.jms.MapMessage;
033: import javax.jms.Message;
034: import javax.jms.MessageConsumer;
035: import javax.jms.Queue;
036: import javax.jms.Session;
037: import javax.jms.Topic;
038: import javax.jms.TopicConnection;
039: import javax.jms.TopicConnectionFactory;
040: import javax.jms.TopicPublisher;
041: import javax.jms.TopicSession;
042: import javax.naming.NamingException;
043: import javax.rmi.PortableRemoteObject;
044: import org.objectweb.jonas.jtests.beans.secured.BaseS;
045: import org.objectweb.jonas.jtests.beans.secured.BaseSHome;
046: import org.objectweb.jonas.jtests.beans.secured.Session1;
047: import org.objectweb.jonas.jtests.beans.secured.Session1Home;
048: import org.objectweb.jonas.jtests.util.JTestCase;
049: import junit.framework.Test;
050: import junit.framework.TestSuite;
051: import org.objectweb.security.context.SecurityContext;
052: import org.objectweb.security.context.SecurityCurrent;
053:
054: /**
055: * Security Management Suite with a stateless session as first bean
056: * Test the run-as element
057: *
058: * @author Florent Benoit
059: *
060: */
061:
062: public class F_RunAs extends JTestCase {
063:
064: /**
065: * Bean RunAs
066: */
067: private static String BEAN_HOME_RUNAS = "securedBaseRunAsSLHome";
068:
069: /**
070: * Bean without RunAs
071: */
072: private static String BEAN_HOME_NO_RUNAS = "securedBaseNoRunAsSLHome";
073:
074: /**
075: * Name of the principal 1
076: */
077: protected static String PRINCIPAL1_NAME = "principal1";
078:
079: /**
080: * Name of the principal 2
081: */
082: protected static String PRINCIPAL2_NAME = "principal2";
083:
084: /**
085: * Name of the role 1
086: */
087: protected static String ROLE1_NAME = "role1";
088:
089: /**
090: * Name of the role 2
091: */
092: protected static String ROLE2_NAME = "role2";
093:
094: /**
095: * Home runAs
096: */
097: protected static BaseSHome runAsHome = null;
098:
099: /**
100: * Home no runAs
101: */
102: protected static BaseSHome noRunAsHome = null;
103:
104: /**
105: * Current
106: */
107: protected static SecurityCurrent current = null;
108:
109: /**
110: * principal 1
111: */
112: protected static SecurityContext principal1 = null;
113:
114: /**
115: * principal 2
116: */
117: protected static SecurityContext principal2 = null;
118:
119: /**
120: * Constructor
121: */
122: public F_RunAs(String name) {
123: super (name);
124: }
125:
126: /**
127: * Return the Home runAs
128: */
129: public BaseSHome getRunAsHome() {
130: if (runAsHome == null) {
131: try {
132: runAsHome = (BaseSHome) PortableRemoteObject.narrow(
133: ictx.lookup(BEAN_HOME_RUNAS), BaseSHome.class);
134: } catch (NamingException e) {
135: fail("Cannot get bean home " + BEAN_HOME_RUNAS);
136: }
137: }
138: return runAsHome;
139: }
140:
141: /**
142: * Return the Home no runAs
143: */
144: public BaseSHome getNoRunAsHome() {
145: if (noRunAsHome == null) {
146: try {
147: noRunAsHome = (BaseSHome) PortableRemoteObject.narrow(
148: ictx.lookup(BEAN_HOME_NO_RUNAS),
149: BaseSHome.class);
150: } catch (NamingException e) {
151: fail("Cannot get bean home " + BEAN_HOME_NO_RUNAS);
152: }
153: }
154: return noRunAsHome;
155: }
156:
157: public BaseS getBaseRunAs() throws Exception {
158: return getRunAsHome().create();
159: }
160:
161: public BaseS getBaseNoRunAs() throws Exception {
162: return getNoRunAsHome().create();
163: }
164:
165: /**
166: * init environment:
167: * - load beans
168: */
169: protected void setUp() {
170: super .setUp();
171: if (current == null) {
172: current = SecurityCurrent.getCurrent();
173: String[] roles1 = new String[] { ROLE1_NAME };
174: principal1 = new SecurityContext(PRINCIPAL1_NAME, roles1);
175: String[] roles2 = new String[] { ROLE2_NAME };
176: principal2 = new SecurityContext(PRINCIPAL2_NAME, roles2);
177: }
178: useBeans("secured", true);
179: }
180:
181: /**
182: * This suite is all BMP test cases
183: */
184: public static Test suite() {
185: return new TestSuite(F_RunAs.class);
186: }
187:
188: public static void main(String args[]) {
189: String testtorun = null;
190: // Get args
191: for (int argn = 0; argn < args.length; argn++) {
192: String s_arg = args[argn];
193: Integer i_arg;
194: if (s_arg.equals("-n")) {
195: testtorun = args[++argn];
196: }
197: }
198: if (testtorun == null) {
199: junit.textui.TestRunner.run(suite());
200: } else {
201: junit.textui.TestRunner.run(new F_RunAs(testtorun));
202: }
203: }
204:
205: /**
206: * Test the call on a bean which call another bean without any runAs
207: * The principal must be propagated
208: */
209: public void testNoRunAsAtAll() throws Exception {
210: current.setSecurityContext(principal1);
211: BaseS sl = getBaseNoRunAs();
212: assertEquals(PRINCIPAL1_NAME, sl.getPrincipalName());
213: assertTrue(sl.isCallerInRole(ROLE1_NAME));
214: sl.callBeanNoRunAsWithRole1();
215: sl.remove();
216: }
217:
218: /**
219: * Test the call on a bean which call another bean.
220: * First bean need to have a run-as access, but not the second
221: * The principal must be propagated
222: */
223: public void testRunAsAndNoRunAs() throws Exception {
224: current.setSecurityContext(principal2);
225: BaseS sl = null;
226: try {
227: sl = getBaseRunAs();
228: } catch (Exception e) {
229: fail("Create failed. Role used to access this bean must be role2");
230: }
231: assertEquals(PRINCIPAL2_NAME, sl.getPrincipalName());
232: assertTrue(sl.isCallerInRole(ROLE2_NAME));
233: boolean b = sl.callBeanNoRunAsWithRole2();
234: if (!b) {
235: fail("Cannot call another bean as role for calling the method must be role1 (run-as on the current bean) and not role2 (principal role)");
236: }
237: sl.remove();
238: }
239:
240: /**
241: * Test the run-as with a Timer
242: * First bean implements TimedObject and has the run-as set.
243: * Timeout method calls another bean method protected
244: * @throws Exception Unexpected Test error
245: */
246: public void testRunAsOnTimer() throws Exception {
247: current.setSecurityContext(principal2);
248: BaseS sl = getBaseRunAs();
249: int duration = 5;
250: try {
251: int oldval = sl.getTimerCount();
252: sl.setTimer(duration, 0, 2);
253: sleep(2000);
254: assertEquals("timer expired too quickly", oldval, sl
255: .getTimerCount());
256: sleep(4000);
257: assertEquals("timer did not expired", oldval + 1, sl
258: .getTimerCount());
259: } finally {
260: sl.remove();
261: }
262: }
263:
264: /**
265: * Test the call on a bean which call another bean.
266: * First bean don't need to have a run-as access, but the second does
267: * The principal must be propagated
268: */
269: public void testnoRunAsAndRunAs() throws Exception {
270: current.setSecurityContext(principal1);
271: BaseS sl = null;
272: sl = getBaseNoRunAs();
273: assertEquals(PRINCIPAL1_NAME, sl.getPrincipalName());
274: assertTrue(sl.isCallerInRole(ROLE1_NAME));
275: boolean b = sl.callBeanRunAsWithRole1();
276: if (!b) {
277: fail("Current role is role1 and the bean which is called need to have role2");
278: }
279: sl.remove();
280: }
281:
282: /**
283: * Test the call on a bean which call another bean.
284: * First bean need to have a run-as access and the second too
285: * First run-as is role1 ,second run-as is role3
286: * so the test works if there is an access denied in second bean
287: * The principal must be propagated
288: */
289: public void testRunAsChain() throws Exception {
290: current.setSecurityContext(principal2);
291: BaseS sl = null;
292: try {
293: sl = getBaseRunAs();
294: } catch (Exception e) {
295: fail("Create failed. Maybe role used is role1 but it must be role2 as this bean has got a run-as attribute with role2");
296: }
297: assertEquals(PRINCIPAL2_NAME, sl.getPrincipalName());
298: assertTrue(sl.isCallerInRole(ROLE2_NAME));
299: boolean b = sl.callBeanRunAsWithRole2();
300: if (!b) {
301: fail("Current role is role2 and the bean which is called has got a run as with role1. The next bean need role 2.");
302: }
303: sl.remove();
304: }
305:
306: /**
307: * Test the call on a bean which call another bean, etc
308: * First bean need role2 and has a run-as
309: * After calling a runas bean, it call a no-run as bean
310: * First run-as is role2 ,second run-as is role3 and last call is done on a without runas
311: * The principal must be propagated
312: */
313: public void testRunAsMultipleChain() throws Exception {
314: current.setSecurityContext(principal2);
315: BaseS sl = null;
316: try {
317: sl = getBaseRunAs();
318: } catch (Exception e) {
319: fail("Create failed. Maybe role used is role1 but it must be role2 as this bean has got a run-as attribute with role2");
320: }
321: assertEquals(PRINCIPAL2_NAME, sl.getPrincipalName());
322: assertTrue(sl.isCallerInRole(ROLE2_NAME));
323: boolean b = sl.callBeanRunAsWithRole2();
324: if (!b) {
325: fail("Current role is role2 and the bean which is called has got a run as with role1. The next bean require role1 so it must work");
326: }
327:
328: b = sl.callBeanNoRunAsWithRole2();
329: if (!b) {
330: fail("Current role is role2 and the bean which is called has got a run as with role1. The next bean require role1 so it must work");
331: }
332:
333: sl.remove();
334: }
335:
336: /**
337: * Test call on protected beans, some beans have run-as roles
338: * It also use LoginContext to authenticate
339: * This test come from user Alexander Daryin
340: * This testcase test the problem of the order in ejb-jar.xml of the permissions
341: */
342: public void testRunAsAndSecurityOrderDeclaration() throws Exception {
343: current.setSecurityContext(principal1);
344: final Session1Home home = (Session1Home) PortableRemoteObject
345: .narrow(ictx.lookup("securedSession1EJB"),
346: Session1Home.class);
347: final Session1 bean = home.create();
348: String resultTest = bean.test();
349: if (!("value".equals(resultTest))) {
350: fail("The return value must be 'value' instead of '"
351: + resultTest + "'");
352: }
353:
354: }
355:
356: /**
357: * Send a message to a MDB which create another bean with its run-as role
358: * MDB send to a queue the answer to see if the test is ok or fail
359: */
360: public void testRunAsJms() throws Exception {
361: current.setSecurityContext(principal2);
362:
363: TopicConnectionFactory tcf = null;
364: TopicConnection tc = null;
365: // Lookup Connection Factories
366: try {
367: tcf = (TopicConnectionFactory) ictx.lookup("JTCF");
368: } catch (NamingException e) {
369: fail("Cannot lookup Connection Factories");
370: }
371:
372: // Create Connections
373: try {
374: tc = tcf.createTopicConnection();
375: } catch (JMSException e) {
376: fail("Cannot create connections");
377: }
378:
379: TopicSession ss = null;
380: try {
381: ss = tc.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
382: } catch (JMSException e) {
383: fail("Cannot create Session: " + e);
384: }
385:
386: Topic topic = null;
387: try {
388: topic = (Topic) ictx.lookup("runAsTopic");
389: } catch (Exception e) {
390: fail("Cannot lookup Topic: " + e);
391: }
392:
393: // Create the TopicPublisher
394: TopicPublisher publisher = null;
395: try {
396: publisher = ss.createPublisher(topic);
397: } catch (JMSException e) {
398: fail("Cannot create TopicPublisher: " + e);
399: }
400:
401: // Publish messages on the queue
402: try {
403: MapMessage mess = ss.createMapMessage();
404: mess.setString("Id", "test");
405: publisher.publish(mess);
406: } catch (JMSException e) {
407: fail("Cannot send message: " + e);
408: }
409:
410: // No close else it fails with JDK 1.3
411: try {
412: ss.close();
413: tc.close();
414: } catch (JMSException e) {
415: fail("Cannot close session: " + e);
416: }
417:
418: // Now receive the message to test if the test is ok or not
419: String msgtxt = null;
420: try {
421: ConnectionFactory cf = (ConnectionFactory) ictx
422: .lookup("JCF");
423: Queue queue = (Queue) ictx.lookup("sampleQueue");
424: Connection conn = cf.createConnection();
425: Session sess = conn.createSession(true,
426: Session.AUTO_ACKNOWLEDGE);
427: MessageConsumer mc = sess
428: .createConsumer((Destination) queue);
429: conn.start();
430: Message message = (Message) mc.receive(10000);
431: if (message == null) {
432: fail("Can not receive message");
433: }
434: msgtxt = message.getStringProperty("testRunAsJms");
435: sess.close();
436: conn.close();
437: } catch (Exception e) {
438: fail("Can not get answer of the jms " + e);
439: }
440:
441: if (msgtxt == null) {
442: fail("No message received from the bean");
443: }
444:
445: if (!msgtxt.equals("ok")) {
446: fail("The test is not ok : " + msgtxt);
447: }
448:
449: }
450:
451: }
|