/**********************************************************************************
*
* $Id: UserDirectoryServiceGetTest.java 105077 2012-02-24 22:54:29Z ottenhoff@longsight.com $
*
***********************************************************************************
*
* Copyright (c) 2007, 2008 Sakai Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaiproject.user.impl.test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import junit.extensions.TestSetup;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.test.SakaiKernelTestBase;
import org.sakaiproject.tool.api.SessionManager;
import org.sakaiproject.user.api.User;
import org.sakaiproject.user.api.UserAlreadyDefinedException;
import org.sakaiproject.user.api.UserDirectoryProvider;
import org.sakaiproject.user.api.UserDirectoryService;
import org.sakaiproject.user.api.UserEdit;
import org.sakaiproject.user.api.UserFactory;
import org.sakaiproject.user.api.UserIdInvalidException;
import org.sakaiproject.user.api.UserNotDefinedException;
import org.sakaiproject.user.api.UserPermissionException;
import org.sakaiproject.user.impl.DbUserService;
import org.sakaiproject.util.BaseResourceProperties;
/**
*
*/
public class UserDirectoryServiceGetTest extends SakaiKernelTestBase {
private static Log log = LogFactory.getLog(UserDirectoryServiceGetTest.class);
private static String USER_SOURCE_PROPERTY = "user.source";
private static Map<String, String> eidToId = new HashMap<String, String>();
private static TestProvider userDirectoryProvider;
private UserDirectoryService userDirectoryService;
/**
* Because framework service calls create so many irreversible side-effects,
* we don't want to keep a single instance of the component manager alive
* for all test classes. On the other hand, we'd rather not take the
* overhead of starting up the component manager for every method in the
* test class. As a compromise, we run a test suite consisting only of the
* class itself.
*
* @throws Exception
*/
public static Test suite() {
TestSetup setup = new TestSetup(new TestSuite(UserDirectoryServiceGetTest.class)) {
protected void setUp() throws Exception {
if (log.isDebugEnabled()) log.debug("starting setup");
try {
oneTimeSetup();
oneTimeSetupAfter();
} catch (Exception e) {
log.warn(e);
}
if (log.isDebugEnabled()) log.debug("finished setup");
}
protected void tearDown() throws Exception {
oneTimeTearDown();
}
};
return setup;
}
private static void oneTimeSetupAfter() throws Exception {
userDirectoryProvider = new TestProvider();
// This is a workaround until we can make it easier to load sakai.properties
// for specific integration tests.
DbUserService dbUserService = (DbUserService)getService(UserDirectoryService.class.getName());
dbUserService.setProvider(userDirectoryProvider);
// Sakai user services very helpfully lowercase input EIDs rather than leaving them alone.
addUserWithEid(dbUserService, "localuser");
addUserWithEid(dbUserService, "localfromauthn");
addUserWithEid(dbUserService, "localwithproviderauthn");
addUserWithEid(dbUserService, "localwithfailedproviderauthn");
}
private static void loginAs(String userId) {
SessionManager sessionManager = (SessionManager)getService(SessionManager.class.getName());
sessionManager.getCurrentSession().setUserId(userId);
}
private static User addUserWithEid(UserDirectoryService userDirectoryService, String eid) throws Exception {
BaseResourceProperties props = new BaseResourceProperties();
props.addProperty(USER_SOURCE_PROPERTY, "local");
User user = userDirectoryService.addUser(null, eid, "J. " + eid, "de " + eid, eid + "@somewhere.edu", eid + "pwd", "Guest", props);
eidToId.put(eid, user.getId());
log.debug("addUser eid=" + eid + ", id=" + user.getId());
return user;
}
private static UserEdit setAsExpected(UserEdit user, boolean isLocal) {
String eid = user.getEid();
user.setEmail(eid + "@somewhere.edu");
user.setFirstName("J. " + eid);
user.setLastName("de " + eid);
user.setPassword(eid + "pwd");
String type = isLocal ? "Guest" : "Student";
user.setType(type);
String source = isLocal ? "local" : "provided";
user.getPropertiesEdit().addProperty(USER_SOURCE_PROPERTY, source);
return user;
}
private static boolean isAsExpected(User user, String eid, boolean isLocal) {
if (eid == null) {
fail("eid is null");
}
if (eidToId.get(eid) == null) {
eidToId.put(eid, user.getId());
}
boolean isMatch = (eid.equals(user.getEid()) &&
user.getId().equals(eidToId.get(eid)) &&
user.getEmail().equals(eid + "@somewhere.edu") &&
user.getFirstName().equals("J. " + eid) &&
user.getLastName().equals("de " + eid) &&
(
(isLocal && user.getType().equals("Guest") && "local".equals(user.getProperties().get(USER_SOURCE_PROPERTY))) ||
(!isLocal && user.getType().equals("Student") && "provided".equals(user.getProperties().get(USER_SOURCE_PROPERTY)))
)
);
if (!isMatch) log.debug("For eid=" + eid + ", user eid=" + user.getEid() + ", id=" + user.getId() + ", email=" + user.getEmail() + ", first=" + user.getFirstName() + ", last=" + user.getLastName());
return isMatch;
}
public void setUp() throws Exception {
log.debug("Setting up UserDirectoryServiceIntegrationTest");
userDirectoryService = (UserDirectoryService)getService(UserDirectoryService.class.getName());
}
public void testLocalUser() throws Exception {
User user = userDirectoryService.getUserByEid("localuser");
Assert.assertTrue(isAsExpected(user, "localuser", true));
List<User> users = userDirectoryService.getUsers();
Assert.assertTrue(users.size() >= 4); // Will probably also include "admin" and "postmaster"
}
public void testLocalUserByEmail() throws Exception {
// Get into cache.
User user = userDirectoryService.getUserByEid("localuser");
Collection<User> users = userDirectoryService.findUsersByEmail("localuser" + "@somewhere.edu");
Assert.assertTrue(users.size() == 1);
user = (User)users.iterator().next();
Assert.assertTrue(isAsExpected(user, "localuser", true));
String userId = user.getId();
// We need to be logged in to change a user record, although not to create one.
loginAs("admin");
UserEdit userEdit = userDirectoryService.editUser(userId);
userEdit.setEmail("razzle@somewhere.edu");
userDirectoryService.commitEdit(userEdit);
// Check that caches were updated.
user = userDirectoryService.getUser(userId);
Assert.assertTrue("razzle@somewhere.edu".equals(user.getEmail()));
users = userDirectoryService.findUsersByEmail("razzle@somewhere.edu");
Assert.assertTrue(users.size() == 1);
user = (User)users.iterator().next();
Assert.assertTrue("localuser".equals(user.getEid()));
// Return to where we were.
userEdit = userDirectoryService.editUser(userId);
userEdit.setEmail("localuser@somewhere.edu");
userDirectoryService.commitEdit(userEdit);
}
public void testLocalUserByAuthn() throws Exception {
User user = userDirectoryService.authenticate("localfromauthn", "WRONGpwd");
Assert.assertTrue(user == null);
user = userDirectoryService.authenticate("localfromauthn", "localfromauthn" + "pwd");
Assert.assertTrue(isAsExpected(user, "localfromauthn", true));
}
public void testLocalUserGetEid() throws Exception {
String eid = userDirectoryService.getUserEid(eidToId.get("localuser"));
Assert.assertTrue("localuser".equals(eid));
}
public void testLocalUserGetId() throws Exception {
String id = userDirectoryService.getUserId("localuser");
Assert.assertTrue(eidToId.get("localuser").equals(id));
}
public void testLocalUserEidEdit() throws Exception {
String localuserId = eidToId.get("localuser");
// Only test EID changing if EIDs are different from IDs.
// Currently there's no way for clients to directly find out whether separate IDs and EIDs are
// supported, and so we guess at it by looking at what ID was given to an existing record.
boolean separateIdEid = !localuserId.equals("localuser");
if (separateIdEid) {
loginAs("admin");
UserEdit userEdit = userDirectoryService.editUser(localuserId);
userEdit.setEid("razzle");
userDirectoryService.commitEdit(userEdit);
String eid = userDirectoryService.getUserEid(localuserId);
Assert.assertTrue("razzle".equals(eid));
String id = userDirectoryService.getUserId("razzle");
Assert.assertTrue(localuserId.equals(id));
// Return to where we were.
userEdit = userDirectoryService.editUser(localuserId);
userEdit.setEid("localuser");
userDirectoryService.commitEdit(userEdit);
}
}
public void testLocalUserNameEdit() throws Exception {
String localuserId = eidToId.get("localuser");
UserEdit userEdit = null;
User user = null;
loginAs("admin");
// check for basic edit
userEdit = userDirectoryService.editUser(localuserId);
String originalFirstName = userEdit.getFirstName();
String originalLastName = userEdit.getLastName();
userEdit.setFirstName("Aaron");
userEdit.setLastName("Zeckoski");
userDirectoryService.commitEdit(userEdit);
user = userDirectoryService.getUser(localuserId);
Assert.assertEquals("Aaron", user.getFirstName());
Assert.assertEquals("Zeckoski", user.getLastName());
// check https://jira.sakaiproject.org/browse/SAK-20226
userEdit = userDirectoryService.editUser(localuserId);
userEdit.setFirstName("<b>Aaron</b>");
userEdit.setLastName("Zeckoski<script>alert(document.cookie)</script>");
userDirectoryService.commitEdit(userEdit);
user = userDirectoryService.getUser(localuserId);
Assert.assertEquals("Aaron", user.getFirstName());
Assert.assertEquals("Zeckoskialert(document.cookie)", user.getLastName());
// Return to where we were.
userEdit = userDirectoryService.editUser(localuserId);
userEdit.setFirstName(originalFirstName);
userEdit.setLastName(originalLastName);
userDirectoryService.commitEdit(userEdit);
}
public void testLocalUserRemove() throws Exception {
// We need to be logged in to change a user record, although not to create one.
loginAs("admin");
UserEdit userEdit = userDirectoryService.editUser(eidToId.get("localuser"));
userDirectoryService.removeUser(userEdit);
User user = null;
try {
user = userDirectoryService.getUserByEid("localuser");
if (user != null) log.debug("After removeUser, user eid=" + user.getEid() + ", id=" + user.getId());
} catch (UserNotDefinedException e) {
}
try {
user = userDirectoryService.getUser(eidToId.get("localuser"));
if (user != null) log.debug("After removeUser, user eid=" + user.getEid() + ", id=" + user.getId());
Assert.fail();
} catch (UserNotDefinedException e) {
}
addUserWithEid(userDirectoryService, "localuser");
}
public void testProvidedUsers() throws Exception {
User user = userDirectoryService.getUserByEid("provideduser");
Assert.assertTrue(isAsExpected(user, "provideduser", false));
String userId = userDirectoryService.getUserId("providedthroughid");
user = userDirectoryService.getUser(userId);
Assert.assertTrue(isAsExpected(user, "providedthroughid", false));
Collection<User> users = userDirectoryService.findUsersByEmail("provideduser@somewhere.edu");
Assert.assertTrue(users.size() == 1);
user = (User)users.iterator().next();
Assert.assertTrue(isAsExpected(user, "provideduser", false));
try {
user = userDirectoryService.getUserByEid("nosuchuser");
Assert.fail();
} catch (UserNotDefinedException e) {
}
}
public void testProvidedAuthentication() throws Exception {
User user = userDirectoryService.authenticate("providedfromauthn", "providedfromauthn" + "Ppwd");
Assert.assertTrue(isAsExpected(user, "providedfromauthn", false));
user = userDirectoryService.authenticate("localwithproviderauthn", "localwithproviderauthn" + "Ppwd");
Assert.assertTrue(isAsExpected(user, "localwithproviderauthn", true));
user = userDirectoryService.authenticate("localwithfailedproviderauthn", "localwithfailedproviderauthn" + "pwd");
Assert.assertTrue(isAsExpected(user, "localwithfailedproviderauthn", true));
}
public void testGetUsersThroughIds() throws Exception {
Collection<String> mappedIds = eidToId.values();
log.debug("have " + mappedIds.size() + " mapped IDs");
List<String> searchIds = new ArrayList<String>(mappedIds);
searchIds.add("NoSuchId");
List<User> users = userDirectoryService.getUsers(searchIds);
log.debug("Return from getUsers=" + users);
Assert.assertTrue(users.size() == (searchIds.size() - 1));
}
public void testCannotChangeUserId() throws Exception {
UserEdit newUser = ((UserFactory)userDirectoryService).newUser();
newUser.setId("homegrownid");
Assert.assertTrue(newUser.getId().equals("homegrownid"));
try {
newUser.setId("changedid");
Assert.fail();
} catch (UnsupportedOperationException e) {
}
}
public void testNoDuplicateUserEid() throws Exception {
String eid = "localuser";
try {
userDirectoryService.addUser(null, eid, "J. " + eid, "de " + eid, eid + "@somewhere.edu", eid + "pwd", "Guest", null);
Assert.fail();
} catch (Exception e) {
}
}
public void testDefaultDisplayIdAndName() throws Exception {
String eid = "localuser";
User user = userDirectoryService.getUserByEid(eid);
Assert.assertEquals(user.getFirstName() + " " + user.getLastName(), user.getDisplayName());
Assert.assertEquals(eid, user.getDisplayId());
}
/**
* We should get a predicatable error on trying to create a user with an Eid longer than supported
*/
public void testLongEid() {
String eid = "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";
try {
userDirectoryService.addUser(null, eid);
Assert.fail();
} catch (UserIdInvalidException e) {
e.printStackTrace();
} catch (UserAlreadyDefinedException e) {
Assert.fail();
} catch (UserPermissionException e) {
Assert.fail();
}
}
public static class TestProvider implements UserDirectoryProvider {
public boolean authenticateUser(String eid, UserEdit userEdit, String password) {
if (eid.equals("providedfromauthn")) {
setAsExpected(userEdit, false);
return true;
} else if (eid.equals("localwithproviderauthn")) {
return true;
} else {
return false;
}
}
public boolean authenticateWithProviderFirst(String eid) {
return !eid.equals("localfromauthn");
}
public boolean findUserByEmail(UserEdit userEdit, String email) {
log.debug("findUserByEmail email=" + email);
String[] parts = email.split("@");
String eid = parts[0];
if (eid.startsWith("provided")) {
userEdit.setEid(eid);
setAsExpected(userEdit, false);
return true;
} else {
return false;
}
}
public boolean getUser(UserEdit userEdit) {
String eid = userEdit.getEid();
log.debug("getUser eid=" + eid + ", id=" + userEdit.getId() + ", email=" + userEdit.getEmail());
if (eid.startsWith("provided")) {
setAsExpected(userEdit, false);
return true;
} else {
return false;
}
}
@SuppressWarnings("unchecked")
public void getUsers(Collection users) {
for (Iterator<User> iter = users.iterator(); iter.hasNext(); ) {
UserEdit userEdit = (UserEdit)iter.next();
if (!getUser(userEdit)) {
iter.remove();
}
}
}
}
}