001: package com.ecyrd.jspwiki.auth;
002:
003: import java.security.Principal;
004: import java.util.Collection;
005: import java.util.List;
006: import java.util.Properties;
007:
008: import org.apache.commons.lang.ArrayUtils;
009:
010: import junit.framework.TestCase;
011:
012: import com.ecyrd.jspwiki.*;
013: import com.ecyrd.jspwiki.auth.authorize.Group;
014: import com.ecyrd.jspwiki.auth.authorize.GroupManager;
015: import com.ecyrd.jspwiki.auth.permissions.PermissionFactory;
016: import com.ecyrd.jspwiki.auth.user.*;
017: import com.ecyrd.jspwiki.workflow.*;
018:
019: /**
020: * @author Andrew Jaquith
021: */
022: public class UserManagerTest extends TestCase {
023:
024: private TestEngine m_engine;
025: private UserManager m_mgr;
026: private UserDatabase m_db;
027:
028: /**
029: * @see junit.framework.TestCase#setUp()
030: */
031: protected void setUp() throws Exception {
032: super .setUp();
033: Properties props = new Properties();
034: props.load(TestEngine.findTestProperties());
035:
036: // Make sure user profile save workflow is OFF
037: props.remove("jspwiki.approver" + UserManager.SAVE_APPROVER);
038:
039: // Make sure we are using the XML user database
040: props.put(XMLUserDatabase.PROP_USERDATABASE,
041: "tests/etc/userdatabase.xml");
042: m_engine = new TestEngine(props);
043: m_mgr = m_engine.getUserManager();
044: m_db = m_mgr.getUserDatabase();
045: }
046:
047: /** Call this setup program to use the save-profile workflow. */
048: protected void setUpWithWorkflow() throws Exception {
049: Properties props = new Properties();
050: props.load(TestEngine.findTestProperties());
051:
052: // Turn on user profile saves by the Admin group
053: props.put("jspwiki.approver." + UserManager.SAVE_APPROVER,
054: "Admin");
055:
056: // Make sure we are using the XML user database
057: props.put(XMLUserDatabase.PROP_USERDATABASE,
058: "tests/etc/userdatabase.xml");
059: m_engine = new TestEngine(props);
060: m_mgr = m_engine.getUserManager();
061: m_db = m_mgr.getUserDatabase();
062: }
063:
064: public void testSetRenamedUserProfile() throws Exception {
065: // First, count the number of users, groups, and pages
066: int oldUserCount = m_db.getWikiNames().length;
067: GroupManager groupManager = m_engine.getGroupManager();
068: PageManager pageManager = m_engine.getPageManager();
069: AuthorizationManager authManager = m_engine
070: .getAuthorizationManager();
071: int oldGroupCount = groupManager.getRoles().length;
072: int oldPageCount = pageManager.getTotalPageCount();
073:
074: // Setup Step 1: create a new user with random name
075: WikiSession session = m_engine.guestSession();
076: long now = System.currentTimeMillis();
077: String oldLogin = "TestLogin" + now;
078: String oldName = "Test User " + now;
079: String newLogin = "RenamedLogin" + now;
080: String newName = "Renamed User " + now;
081: UserProfile profile = new DefaultUserProfile();
082: profile.setEmail("testuser@testville.com");
083: profile.setLoginName(oldLogin);
084: profile.setFullname(oldName);
085: profile.setPassword("password");
086: m_mgr.setUserProfile(session, profile);
087:
088: // 1a. Make sure the profile saved successfully
089: profile = m_mgr.getUserProfile(session);
090: assertEquals(oldLogin, profile.getLoginName());
091: assertEquals(oldName, profile.getFullname());
092: assertEquals(oldUserCount + 1, m_db.getWikiNames().length);
093:
094: // Setup Step 2: create a new group with our test user in it
095: String groupName = "Group" + now;
096: Group group = groupManager.parseGroup(groupName,
097: "Alice \n Bob \n Charlie \n " + oldLogin + "\n"
098: + oldName, true);
099: groupManager.setGroup(session, group);
100:
101: // 2a. Make sure the group is created with the user in it, and the role is added to the Subject
102: assertEquals(oldGroupCount + 1, groupManager.getRoles().length);
103: assertTrue(group.isMember(new WikiPrincipal(oldLogin)));
104: assertTrue(group.isMember(new WikiPrincipal(oldName)));
105: assertFalse(group.isMember(new WikiPrincipal(newLogin)));
106: assertFalse(group.isMember(new WikiPrincipal(newName)));
107: assertTrue(groupManager.isUserInRole(session, group
108: .getPrincipal()));
109:
110: // Setup Step 3: create a new page with our test user in the ACL
111: String pageName = "TestPage" + now;
112: m_engine.saveText(pageName, "Test text. [{ALLOW view "
113: + oldName + ", " + oldLogin + ", Alice}] More text.");
114:
115: // 3a. Make sure the page got saved, and that ONLY our test user has permission to read it.
116: WikiPage p = m_engine.getPage(pageName);
117: assertEquals(oldPageCount + 1, pageManager.getTotalPageCount());
118: assertNotNull(p.getAcl().getEntry(new WikiPrincipal(oldLogin)));
119: assertNotNull(p.getAcl().getEntry(new WikiPrincipal(oldName)));
120: assertNull(p.getAcl().getEntry(new WikiPrincipal(newLogin)));
121: assertNull(p.getAcl().getEntry(new WikiPrincipal(newName)));
122: assertTrue("Test User view page", authManager
123: .checkPermission(session, PermissionFactory
124: .getPagePermission(p, "view")));
125: WikiSession bobSession = WikiSessionTest.authenticatedSession(
126: m_engine, Users.BOB, Users.BOB_PASS);
127: assertFalse("Bob !view page", authManager.checkPermission(
128: bobSession, PermissionFactory.getPagePermission(p,
129: "view")));
130:
131: // Setup Step 4: change the user name in the profile and see what happens
132: profile = new DefaultUserProfile();
133: profile.setEmail("testuser@testville.com");
134: profile.setLoginName(oldLogin);
135: profile.setFullname(newName);
136: profile.setPassword("password");
137: m_mgr.setUserProfile(session, profile);
138:
139: // Test 1: the wiki session should have the new wiki name in Subject
140: Principal[] principals = session.getPrincipals();
141: assertTrue(ArrayUtils.contains(principals, new WikiPrincipal(
142: oldLogin)));
143: assertFalse(ArrayUtils.contains(principals, new WikiPrincipal(
144: oldName)));
145: assertFalse(ArrayUtils.contains(principals, new WikiPrincipal(
146: newLogin)));
147: assertTrue(ArrayUtils.contains(principals, new WikiPrincipal(
148: newName)));
149:
150: // Test 2: our group should not contain the old name OR login name any more
151: // (the full name is always used)
152: group = groupManager.getGroup(groupName);
153: assertFalse(group.isMember(new WikiPrincipal(oldLogin)));
154: assertFalse(group.isMember(new WikiPrincipal(oldName)));
155: assertFalse(group.isMember(new WikiPrincipal(newLogin)));
156: assertTrue(group.isMember(new WikiPrincipal(newName)));
157:
158: // Test 3: our page should not contain the old wiki name OR login name
159: // in the ACL any more (the full name is always used)
160: p = m_engine.getPage(pageName);
161: assertNull(p.getAcl().getEntry(new WikiPrincipal(oldLogin)));
162: assertNull(p.getAcl().getEntry(new WikiPrincipal(oldName)));
163: assertNull(p.getAcl().getEntry(new WikiPrincipal(newLogin)));
164: assertNotNull(p.getAcl().getEntry(new WikiPrincipal(newName)));
165: assertTrue("Test User view page", authManager
166: .checkPermission(session, PermissionFactory
167: .getPagePermission(p, "view")));
168: assertFalse("Bob !view page", authManager.checkPermission(
169: bobSession, PermissionFactory.getPagePermission(p,
170: "view")));
171:
172: // Test 4: our page text should have been re-written
173: // (The new full name should be in the ACL, but the login name should have been removed)
174: String expectedText = "[{ALLOW view Alice," + newName
175: + "}]\nTest text. More text.\r\n";
176: String actualText = m_engine.getText(pageName);
177: assertEquals(expectedText, actualText);
178:
179: // Remove our test page
180: m_engine.deletePage(pageName);
181:
182: // Setup Step 6: re-create the group with our old test user names in it
183: group = groupManager.parseGroup(groupName,
184: "Alice \n Bob \n Charlie \n " + oldLogin + "\n"
185: + oldName, true);
186: groupManager.setGroup(session, group);
187:
188: // Setup Step 7: Save a new page with the old login/wiki names in the ACL again
189: // The test user should still be able to see the page (because the login name matches...)
190: pageName = "TestPage2" + now;
191: m_engine.saveText(pageName, "More test text. [{ALLOW view "
192: + oldName + ", " + oldLogin + ", Alice}] More text.");
193: p = m_engine.getPage(pageName);
194: assertEquals(oldPageCount + 1, pageManager.getTotalPageCount());
195: assertNotNull(p.getAcl().getEntry(new WikiPrincipal(oldLogin)));
196: assertNotNull(p.getAcl().getEntry(new WikiPrincipal(oldName)));
197: assertNull(p.getAcl().getEntry(new WikiPrincipal(newLogin)));
198: assertNull(p.getAcl().getEntry(new WikiPrincipal(newName)));
199: assertTrue("Test User view page", authManager
200: .checkPermission(session, PermissionFactory
201: .getPagePermission(p, "view")));
202: assertFalse("Bob !view page", authManager.checkPermission(
203: bobSession, PermissionFactory.getPagePermission(p,
204: "view")));
205:
206: // Setup Step 8: re-save the profile with the new login name
207: profile = new DefaultUserProfile();
208: profile.setEmail("testuser@testville.com");
209: profile.setLoginName(newLogin);
210: profile.setFullname(oldName);
211: profile.setPassword("password");
212: m_mgr.setUserProfile(session, profile);
213:
214: // Test 5: the wiki session should have the new login name in Subject
215: principals = session.getPrincipals();
216: assertFalse(ArrayUtils.contains(principals, new WikiPrincipal(
217: oldLogin)));
218: assertTrue(ArrayUtils.contains(principals, new WikiPrincipal(
219: oldName)));
220: assertTrue(ArrayUtils.contains(principals, new WikiPrincipal(
221: newLogin)));
222: assertFalse(ArrayUtils.contains(principals, new WikiPrincipal(
223: newName)));
224:
225: // Test 6: our group should not contain the old name OR login name any more
226: // (the full name is always used)
227: group = groupManager.getGroup(groupName);
228: assertFalse(group.isMember(new WikiPrincipal(oldLogin)));
229: assertTrue(group.isMember(new WikiPrincipal(oldName)));
230: assertFalse(group.isMember(new WikiPrincipal(newLogin)));
231: assertFalse(group.isMember(new WikiPrincipal(newName)));
232:
233: // Test 7: our page should not contain the old wiki name OR login name
234: // in the ACL any more (the full name is always used)
235: p = m_engine.getPage(pageName);
236: assertNull(p.getAcl().getEntry(new WikiPrincipal(oldLogin)));
237: assertNotNull(p.getAcl().getEntry(new WikiPrincipal(oldName)));
238: assertNull(p.getAcl().getEntry(new WikiPrincipal(newLogin)));
239: assertNull(p.getAcl().getEntry(new WikiPrincipal(newName)));
240: assertTrue("Test User view page", authManager
241: .checkPermission(session, PermissionFactory
242: .getPagePermission(p, "view")));
243: assertFalse("Bob !view page", authManager.checkPermission(
244: bobSession, PermissionFactory.getPagePermission(p,
245: "view")));
246:
247: // Test 8: our page text should have been re-written
248: // (The new full name should be in the ACL, but the login name should have been removed)
249: expectedText = "[{ALLOW view Alice," + oldName
250: + "}]\nMore test text. More text.\r\n";
251: actualText = m_engine.getText(pageName);
252: assertEquals(expectedText, actualText);
253:
254: // CLEANUP: delete the profile; user and page; should be back to old counts
255: m_db.deleteByLoginName(newLogin);
256: assertEquals(oldUserCount, m_db.getWikiNames().length);
257:
258: groupManager.removeGroup(group.getName());
259: assertEquals(oldGroupCount, groupManager.getRoles().length);
260:
261: m_engine.deletePage(pageName);
262: assertEquals(oldPageCount, pageManager.getTotalPageCount());
263: }
264:
265: public void testSetUserProfile() throws Exception {
266: // First, count the number of users in the db now.
267: int oldUserCount = m_db.getWikiNames().length;
268:
269: // Create a new user with random name
270: WikiSession session = m_engine.guestSession();
271: String loginName = "TestUser"
272: + String.valueOf(System.currentTimeMillis());
273: UserProfile profile = new DefaultUserProfile();
274: profile.setEmail("testuser@testville.com");
275: profile.setLoginName(loginName);
276: profile.setFullname("FullName" + loginName);
277: profile.setPassword("password");
278: m_mgr.setUserProfile(session, profile);
279:
280: // Make sure the profile saved successfully
281: profile = m_mgr.getUserProfile(session);
282: assertEquals(loginName, profile.getLoginName());
283: assertEquals(oldUserCount + 1, m_db.getWikiNames().length);
284:
285: // Now delete the profile; should be back to old count
286: m_db.deleteByLoginName(loginName);
287: assertEquals(oldUserCount, m_db.getWikiNames().length);
288: }
289:
290: public void testSetUserProfileWithApproval() throws Exception {
291: setUpWithWorkflow();
292:
293: // First, count the number of users in the db now.
294: int oldUserCount = m_db.getWikiNames().length;
295:
296: // Create a new user with random name
297: WikiSession session = m_engine.guestSession();
298: String loginName = "TestUser"
299: + String.valueOf(System.currentTimeMillis());
300: UserProfile profile = new DefaultUserProfile();
301: profile.setEmail("testuser@testville.com");
302: profile.setLoginName(loginName);
303: profile.setFullname("FullName" + loginName);
304: profile.setPassword("password");
305:
306: // Because user profile saves require approvals, we will catch a Redirect
307: try {
308: m_mgr.setUserProfile(session, profile);
309: fail("We should have caught a DecisionRequiredException caused by approval!");
310: } catch (DecisionRequiredException e) {
311: }
312:
313: // The user should NOT be saved yet
314: assertEquals(oldUserCount, m_db.getWikiNames().length);
315:
316: // Now, look in Admin's queue, and verify there's a pending Decision there
317: DecisionQueue dq = m_engine.getWorkflowManager()
318: .getDecisionQueue();
319: Collection decisions = dq.getActorDecisions(m_engine
320: .adminSession());
321: assertEquals(1, decisions.size());
322:
323: // Verify that the Decision has all the facts and attributes we need
324: Decision d = (Decision) decisions.iterator().next();
325: List facts = d.getFacts();
326: assertEquals(new Fact(UserManager.PREFS_FULL_NAME, profile
327: .getFullname()), facts.get(0));
328: assertEquals(new Fact(UserManager.PREFS_LOGIN_NAME, profile
329: .getLoginName()), facts.get(1));
330: assertEquals(new Fact(UserManager.FACT_SUBMITTER, session
331: .getUserPrincipal().getName()), facts.get(2));
332: assertEquals(new Fact(UserManager.PREFS_EMAIL, profile
333: .getEmail()), facts.get(3));
334: assertEquals(profile, d.getWorkflow().getAttribute(
335: UserManager.SAVED_PROFILE));
336:
337: // Approve the profile
338: d.decide(Outcome.DECISION_APPROVE);
339:
340: // Make sure the profile saved successfully
341: assertEquals(oldUserCount + 1, m_db.getWikiNames().length);
342:
343: // Now delete the profile; should be back to old count
344: m_db.deleteByLoginName(loginName);
345: assertEquals(oldUserCount, m_db.getWikiNames().length);
346: }
347:
348: public void testSetUserProfileWithDenial() throws Exception {
349: setUpWithWorkflow();
350:
351: // First, count the number of users in the db now.
352: int oldUserCount = m_db.getWikiNames().length;
353:
354: // Create a new user with random name
355: WikiSession session = m_engine.guestSession();
356: String loginName = "TestUser"
357: + String.valueOf(System.currentTimeMillis());
358: UserProfile profile = new DefaultUserProfile();
359: profile.setEmail("testuser@testville.com");
360: profile.setLoginName(loginName);
361: profile.setFullname("FullName" + loginName);
362: profile.setPassword("password");
363:
364: // Because user profile saves require approvals, we will catch a Redirect
365: try {
366: m_mgr.setUserProfile(session, profile);
367: fail("We should have caught a DecisionRequiredException caused by approval!");
368: } catch (DecisionRequiredException e) {
369: }
370:
371: // The user should NOT be saved yet
372: assertEquals(oldUserCount, m_db.getWikiNames().length);
373:
374: // Now, look in Admin's queue, and verify there's a pending Decision there
375: DecisionQueue dq = m_engine.getWorkflowManager()
376: .getDecisionQueue();
377: Collection decisions = dq.getActorDecisions(m_engine
378: .adminSession());
379: assertEquals(1, decisions.size());
380:
381: // Verify that the Decision has all the facts and attributes we need
382: Decision d = (Decision) decisions.iterator().next();
383: List facts = d.getFacts();
384: assertEquals(new Fact(UserManager.PREFS_FULL_NAME, profile
385: .getFullname()), facts.get(0));
386: assertEquals(new Fact(UserManager.PREFS_LOGIN_NAME, profile
387: .getLoginName()), facts.get(1));
388: assertEquals(new Fact(UserManager.FACT_SUBMITTER, session
389: .getUserPrincipal().getName()), facts.get(2));
390: assertEquals(new Fact(UserManager.PREFS_EMAIL, profile
391: .getEmail()), facts.get(3));
392: assertEquals(profile, d.getWorkflow().getAttribute(
393: UserManager.SAVED_PROFILE));
394:
395: // Approve the profile
396: d.decide(Outcome.DECISION_DENY);
397:
398: // Make sure the profile did NOT save
399: assertEquals(oldUserCount, m_db.getWikiNames().length);
400: }
401:
402: public void testSetCollidingUserProfile() throws Exception {
403: // First, count the number of users in the db now.
404: int oldUserCount = m_db.getWikiNames().length;
405:
406: // Create a new user with random name
407: WikiSession session = m_engine.guestSession();
408: String loginName = "TestUser"
409: + String.valueOf(System.currentTimeMillis());
410: UserProfile profile = new DefaultUserProfile();
411: profile.setEmail("testuser@testville.com");
412: profile.setLoginName(loginName);
413: profile.setFullname("FullName" + loginName);
414: profile.setPassword("password");
415:
416: // Set the login name to collide with Janne's: should prohibit saving
417: profile.setLoginName("janne");
418: try {
419: m_mgr.setUserProfile(session, profile);
420: fail("UserManager allowed saving of user with login name 'janne', but it shouldn't have.");
421: } catch (DuplicateUserException e) {
422: // Good! That's what we expected; reset for next test
423: profile.setLoginName(loginName);
424: }
425:
426: // Set the login name to collide with Janne's: should prohibit saving
427: profile.setFullname("Janne Jalkanen");
428: try {
429: m_mgr.setUserProfile(session, profile);
430: fail("UserManager allowed saving of user with login name 'janne', but it shouldn't have.");
431: } catch (DuplicateUserException e) {
432: // Good! That's what we expected
433: }
434:
435: // There shouldn't have been any users added
436: assertEquals(oldUserCount, m_db.getWikiNames().length);
437: }
438:
439: }
|