/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.web.portal.services; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; import com.enonic.esl.containers.ExtendedMap; import com.enonic.cms.api.plugin.ext.userstore.UserFieldType; import com.enonic.cms.api.plugin.ext.userstore.UserStoreConfig; import com.enonic.cms.api.plugin.ext.userstore.UserStoreConfigField; import com.enonic.cms.core.Attribute; import com.enonic.cms.core.portal.httpservices.HttpServicesException; import com.enonic.cms.core.security.PortalSecurityHolder; import com.enonic.cms.core.security.SecurityService; import com.enonic.cms.core.security.group.GroupEntity; import com.enonic.cms.core.security.group.GroupKey; import com.enonic.cms.core.security.group.GroupType; import com.enonic.cms.core.security.user.UpdateUserCommand; import com.enonic.cms.core.security.user.UserEntity; import com.enonic.cms.core.security.user.UserType; import com.enonic.cms.core.security.userstore.StoreNewUserStoreCommand; import com.enonic.cms.core.security.userstore.UserStoreKey; import com.enonic.cms.core.security.userstore.UserStoreService; import com.enonic.cms.core.servlet.ServletRequestAccessor; import com.enonic.cms.core.structure.SiteKey; import com.enonic.cms.core.structure.SitePath; import com.enonic.cms.itest.AbstractSpringTest; import com.enonic.cms.itest.util.DomainFixture; import com.enonic.cms.store.dao.GroupDao; import com.enonic.cms.store.dao.UserDao; import com.enonic.cms.store.dao.UserStoreDao; import com.enonic.cms.web.portal.SiteRedirectHelper; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; import static org.easymock.classextension.EasyMock.createMock; public class UserServicesProcessorTest extends AbstractSpringTest { @Autowired private UserDao userDao; @Autowired private GroupDao groupDao; @Autowired private UserStoreDao userStoreDao; @Autowired private SecurityService securityService; @Autowired private UserStoreService userStoreService; @Autowired private DomainFixture fixture; private MockHttpServletRequest request = new MockHttpServletRequest(); private MockHttpServletResponse response = new MockHttpServletResponse(); private MockHttpSession session = new MockHttpSession(); private UserServicesProcessor userHandlerController; @Before public void setUp() { fixture.initSystemData(); userHandlerController = new UserServicesProcessor(); userHandlerController.setUserDao( userDao ); userHandlerController.setGroupDao( groupDao ); userHandlerController.setUserStoreDao( userStoreDao ); userHandlerController.setSecurityService( securityService ); userHandlerController.setUserStoreService( userStoreService ); userHandlerController.setUserServicesRedirectHelper( new UserServicesRedirectUrlResolver() ); // just need a dummy of the SiteRedirectHelper userHandlerController.setSiteRedirectHelper( createMock( SiteRedirectHelper.class ) ); request.setRemoteAddr( "127.0.0.1" ); ServletRequestAccessor.setRequest( request ); PortalSecurityHolder.setAnonUser( fixture.findUserByName( "anonymous" ).getKey() ); } @After public void after() { securityService.logoutPortalUser(); } // JSI, 2015-04-01: // The following two tests do not seem to test what they should. It seems it only test <code>userHandlerConteroller.addGroupsfromSetGroupsConfig</code> // which is an internal method in the class, where the other tests in this and related classes tests handlerXxx methods. I think this test should test // the <code>handlerSetGroups</code> method. That would make sense. // // Until today, this test and the next one, were exactly equal. The few commetns exising did not make sense, so I have tried to update this test // somewhat. However, I run into problems when I tried to create a data-setup that allowed for real testing of the <code>handlerSetGroups</code> // method, so the test as it stands right now does still not seem to be very interesting. @Test public void testAddGroupsFromSetGroupsConfig() { final GroupEntity group1 = fixture.getFactory().createGroup( "open1", GroupType.GLOBAL_GROUP, false ); fixture.save( group1 ); final GroupEntity group2 = fixture.getFactory().createGroup( "open2", GroupType.GLOBAL_GROUP, false ); fixture.save( group2 ); final GroupEntity group3 = fixture.getFactory().createGroup( "open3", GroupType.USERSTORE_GROUP, false ); fixture.save( group3 ); final GroupEntity testUserGroup = fixture.getFactory().createGroup( "testUserGroup", GroupType.USER, true ); fixture.save( testUserGroup ); final UserEntity testUser = fixture.getFactory().createUser( "testUser", "Test User", UserType.NORMAL, "testuserstore", testUserGroup); fixture.save( testUser ); final String group1Key = group1.getGroupKey().toString(); final String group2Key = group2.getGroupKey().toString(); final String group3Key = group3.getGroupKey().toString(); ExtendedMap formItems = new ExtendedMap(); // User is a member of group 1 // Group 1 is in the allgroupskey, and should be removed since not in joingroupkey // Group 2 and 3 will be added formItems.put( UserServicesProcessor.ALLGROUPKEYS, group1Key ); formItems.put( UserServicesProcessor.JOINGROUPKEY, new String[]{group2Key, group3Key} ); UpdateUserCommand updateUserCommand = new UpdateUserCommand( null, null ); userHandlerController.addGroupsFromSetGroupsConfig( formItems, updateUserCommand, testUser ); List<GroupKey> expectedEntries = generateGroupKeyList( new String[]{group2Key, group3Key} ); assertEquals( "Should have 2 groups", 2, updateUserCommand.getMemberships().size() ); assertTrue( updateUserCommand.getMemberships().containsAll( expectedEntries ) ); } // JSI, 2015-04-01: // This test is exactely what the previous test used to be. Neither makes any sense. The name of this seems to indicate it should test some kind // of negative condition, but it does not. I would say this needs to be rewritten, but it is not clear to what, so for now, I will check this in // with these comments. @Test public void testAddRestricedGroupNotAllowed() { final GroupEntity group1 = fixture.getFactory().createGroup( "open1", GroupType.GLOBAL_GROUP, false ); fixture.save( group1 ); final GroupEntity group2 = fixture.getFactory().createGroup( "open2", GroupType.GLOBAL_GROUP, false ); fixture.save( group2 ); final GroupEntity group3 = fixture.getFactory().createGroup( "open3", GroupType.GLOBAL_GROUP, true ); fixture.save( group3 ); final String group1Key = group1.getGroupKey().toString(); final String group2Key = group2.getGroupKey().toString(); final String group3Key = group3.getGroupKey().toString(); ExtendedMap formItems = new ExtendedMap(); // User has group 1,2,7 // Group 1 is in the allgroupskey, and should be removed since not in joingroupkey // Group 1 and 2 will be added, while group 3 will not since its restricted formItems.put( UserServicesProcessor.ALLGROUPKEYS, "1" ); formItems.put( UserServicesProcessor.JOINGROUPKEY, new String[]{group1Key, group2Key, group3Key} ); UpdateUserCommand updateUserCommand = new UpdateUserCommand( null, null ); MyUserEntityMock user = new MyUserEntityMock(); userHandlerController.addGroupsFromSetGroupsConfig( formItems, updateUserCommand, user ); List<GroupKey> expectedEntries = generateGroupKeyList( new String[]{"2", "7", group1Key, group2Key} ); assertEquals( "Should have 4 groups", 4, updateUserCommand.getMemberships().size() ); assertTrue( updateUserCommand.getMemberships().containsAll( expectedEntries ) ); } @Test public void create_without_required_fields_on_local_user_store_throws_exception() throws Exception { UserStoreConfig userStoreConfig = new UserStoreConfig(); userStoreConfig.addUserFieldConfig( createUserStoreUserFieldConfig( UserFieldType.FIRST_NAME, "required" ) ); userStoreConfig.addUserFieldConfig( createUserStoreUserFieldConfig( UserFieldType.LAST_NAME, "required" ) ); userStoreConfig.addUserFieldConfig( createUserStoreUserFieldConfig( UserFieldType.INITIALS, "required" ) ); createLocalUserStore( "myLocalStore", true, userStoreConfig ); fixture.flushAndClearHibernateSession(); // exercise request.setAttribute( Attribute.ORIGINAL_SITEPATH, new SitePath( new SiteKey( 0 ), "/_services/user/create" ) ); ExtendedMap formItems = createExtendedMap(); formItems.putString( "username", "testcreate" ); formItems.putString( "password", "password" ); formItems.putString( "email", "test@test.com" ); formItems.putString( "first_name", "First name" ); formItems.putString( "last_name", "Last name" ); try { userHandlerController.handlerCreate( request, response, session, formItems, null, null ); fail( "Expected exception" ); } catch ( Exception e ) { assertTrue( e instanceof HttpServicesException ); assertEquals( "Error in http services, error code: 400", e.getMessage() ); } } @Test public void create_with_empty_required_fields_on_local_user_store_throws_exception() throws Exception { UserStoreConfig userStoreConfig = new UserStoreConfig(); userStoreConfig.addUserFieldConfig( createUserStoreUserFieldConfig( UserFieldType.FIRST_NAME, "required" ) ); userStoreConfig.addUserFieldConfig( createUserStoreUserFieldConfig( UserFieldType.LAST_NAME, "required" ) ); userStoreConfig.addUserFieldConfig( createUserStoreUserFieldConfig( UserFieldType.INITIALS, "required" ) ); createLocalUserStore( "myLocalStore", true, userStoreConfig ); fixture.flushAndClearHibernateSession(); // exercise request.setAttribute( Attribute.ORIGINAL_SITEPATH, new SitePath( new SiteKey( 0 ), "/_services/user/create" ) ); ExtendedMap formItems = createExtendedMap(); formItems.putString( "username", "testcreate" ); formItems.putString( "password", "password" ); formItems.putString( "email", "test@test.com" ); formItems.putString( "first_name", "First name" ); formItems.putString( "last_name", "Last name" ); formItems.putString( "initials", "" ); // field set but empty try { userHandlerController.handlerCreate( request, response, session, formItems, null, null ); fail( "Expected exception" ); } catch ( Exception e ) { assertTrue( e instanceof HttpServicesException ); assertEquals( "Error in http services, error code: 400", e.getMessage() ); } } @Test public void create_with_blank_required_fields_on_local_user_store_throws_exception() throws Exception { UserStoreConfig userStoreConfig = new UserStoreConfig(); userStoreConfig.addUserFieldConfig( createUserStoreUserFieldConfig( UserFieldType.FIRST_NAME, "required" ) ); userStoreConfig.addUserFieldConfig( createUserStoreUserFieldConfig( UserFieldType.LAST_NAME, "required" ) ); userStoreConfig.addUserFieldConfig( createUserStoreUserFieldConfig( UserFieldType.INITIALS, "required" ) ); createLocalUserStore( "myLocalStore", true, userStoreConfig ); fixture.flushAndClearHibernateSession(); // exercise request.setAttribute( Attribute.ORIGINAL_SITEPATH, new SitePath( new SiteKey( 0 ), "/_services/user/create" ) ); ExtendedMap formItems = createExtendedMap(); formItems.putString( "username", "testcreate" ); formItems.putString( "password", "password" ); formItems.putString( "email", "test@test.com" ); formItems.putString( "first_name", "First name" ); formItems.putString( "last_name", "Last name" ); formItems.putString( "initials", " " ); // field set but blank try { userHandlerController.handlerCreate( request, response, session, formItems, null, null ); fail( "Expected exception" ); } catch ( Exception e ) { assertTrue( e instanceof HttpServicesException ); assertEquals( "Error in http services, error code: 400", e.getMessage() ); } } private UserStoreConfigField createUserStoreUserFieldConfig( UserFieldType type, String properties ) { UserStoreConfigField fieldConfig = new UserStoreConfigField( type ); fieldConfig.setRemote( properties.contains( "remote" ) ); fieldConfig.setReadOnly( properties.contains( "read-only" ) ); fieldConfig.setRequired( properties.contains( "required" ) ); fieldConfig.setIso( properties.contains( "iso" ) ); return fieldConfig; } private UserStoreKey createLocalUserStore( String name, boolean defaultStore, UserStoreConfig config ) { StoreNewUserStoreCommand command = new StoreNewUserStoreCommand(); command.setStorer( fixture.findUserByName( "admin" ).getKey() ); command.setName( name ); command.setDefaultStore( defaultStore ); command.setConfig( config ); return userStoreService.storeNewUserStore( command ); } private ExtendedMap createExtendedMap() { return new ExtendedMap( true ); } private List<GroupKey> generateGroupKeyList( String[] keys ) { List<GroupKey> groupKeys = new ArrayList<GroupKey>(); for ( String key : keys ) { groupKeys.add( new GroupKey( key ) ); } return groupKeys; } private class MyUserEntityMock extends UserEntity { private static final long serialVersionUID = -5767196099030559184L; @Override public Set<GroupEntity> getDirectMemberships() { GroupEntity group1 = new GroupEntity(); group1.setKey( new GroupKey( "1" ) ); GroupEntity group2 = new GroupEntity(); group2.setKey( new GroupKey( "2" ) ); GroupEntity group7 = new GroupEntity(); group7.setKey( new GroupKey( "7" ) ); Set<GroupEntity> groupEntities = new HashSet<GroupEntity>(); groupEntities.add( group1 ); groupEntities.add( group2 ); groupEntities.add( group7 ); return groupEntities; } } }