/******************************************************************************* * Cloud Foundry * Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved. * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * * This product includes a number of subcomponents with * separate copyright notices and license terms. Your use of these * subcomponents is subject to the terms and conditions of the * subcomponent's license, as noted in the LICENSE file. *******************************************************************************/ package org.cloudfoundry.identity.uaa.scim.bootstrap; import org.cloudfoundry.identity.uaa.resources.jdbc.JdbcPagingListFactory; import org.cloudfoundry.identity.uaa.scim.ScimGroup; import org.cloudfoundry.identity.uaa.scim.ScimGroupMember; import org.cloudfoundry.identity.uaa.scim.jdbc.JdbcScimGroupMembershipManager; import org.cloudfoundry.identity.uaa.scim.jdbc.JdbcScimGroupProvisioning; import org.cloudfoundry.identity.uaa.scim.jdbc.JdbcScimUserProvisioning; import org.cloudfoundry.identity.uaa.scim.test.TestUtils; import org.cloudfoundry.identity.uaa.test.JdbcTestBase; import org.cloudfoundry.identity.uaa.util.MapCollector; import org.cloudfoundry.identity.uaa.util.PredicateMatcher; import org.junit.Before; import org.junit.Test; import org.springframework.core.env.MapPropertySource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.util.StringUtils; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItems; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; public class ScimGroupBootstrapTests extends JdbcTestBase { private JdbcScimGroupProvisioning gDB; private JdbcScimUserProvisioning uDB; private JdbcScimGroupMembershipManager mDB; private ScimGroupBootstrap bootstrap; @Before public void initScimGroupBootstrapTests() { JdbcTemplate template = jdbcTemplate; JdbcPagingListFactory pagingListFactory = new JdbcPagingListFactory(template, limitSqlAdapter); gDB = new JdbcScimGroupProvisioning(template, pagingListFactory); uDB = new JdbcScimUserProvisioning(template, pagingListFactory); mDB = new JdbcScimGroupMembershipManager(template, pagingListFactory); mDB.setScimGroupProvisioning(gDB); mDB.setScimUserProvisioning(uDB); uDB.createUser(TestUtils.scimUserInstance("dev1"), "test"); uDB.createUser(TestUtils.scimUserInstance("dev2"), "test"); uDB.createUser(TestUtils.scimUserInstance("dev3"), "test"); uDB.createUser(TestUtils.scimUserInstance("qa1"), "test"); uDB.createUser(TestUtils.scimUserInstance("qa2"), "test"); uDB.createUser(TestUtils.scimUserInstance("mgr1"), "test"); uDB.createUser(TestUtils.scimUserInstance("hr1"), "test"); assertEquals(7, uDB.retrieveAll().size()); assertEquals(0, gDB.retrieveAll().size()); bootstrap = new ScimGroupBootstrap(gDB, uDB, mDB); } @Test public void canAddGroups() throws Exception { bootstrap.setGroups(StringUtils.commaDelimitedListToSet("org1.dev,org1.qa,org1.engg,org1.mgr,org1.hr").stream().collect(new MapCollector<>(s -> s, s -> null))); bootstrap.afterPropertiesSet(); assertEquals(5, gDB.retrieveAll().size()); assertNotNull(bootstrap.getGroup("org1.dev")); assertNotNull(bootstrap.getGroup("org1.qa")); assertNotNull(bootstrap.getGroup("org1.engg")); assertNotNull(bootstrap.getGroup("org1.mgr")); assertNotNull(bootstrap.getGroup("org1.hr")); } @Test public void testNullGroups() throws Exception { bootstrap.setGroups(null); bootstrap.afterPropertiesSet(); assertEquals(0, gDB.retrieveAll().size()); } @Test public void canAddMembers() throws Exception { bootstrap.setGroupMembers(Arrays.asList( "org1.dev|dev1,dev2,dev3", "org1.dev|hr1,mgr1|write", "org1.qa|qa1,qa2,qa3", "org1.mgr|mgr1", "org1.hr|hr1", "org1.engg|org1.dev,org1.qa,org1.mgr" )); bootstrap.afterPropertiesSet(); assertEquals(5, gDB.retrieveAll().size()); assertEquals(7, uDB.retrieveAll().size()); assertEquals(2, bootstrap.getGroup("org1.qa").getMembers().size()); assertEquals(1, bootstrap.getGroup("org1.hr").getMembers().size()); assertEquals(3, bootstrap.getGroup("org1.engg").getMembers().size()); assertEquals(2, mDB.getMembers(bootstrap.getGroup("org1.dev").getId(), ScimGroupMember.Role.WRITER).size()); } @Test public void stripsWhitespaceFromGroupNamesAndDescriptions() throws Exception { Map<String, String> groups = new HashMap<>(); groups.put("print", "Access the network printer"); groups.put(" something", " Do something else"); bootstrap.setGroups(groups); bootstrap.afterPropertiesSet(); ScimGroup group; assertNotNull(group = bootstrap.getGroup("something")); assertNotNull(group = gDB.retrieve(group.getId())); assertEquals("something", group.getDisplayName()); assertEquals("Do something else", group.getDescription()); } @Test public void fallsBackToMessagesProperties() throws Exception { // set up default groups HashMap<String, Object> defaultDescriptions = new HashMap<>(); defaultDescriptions.put("pets.cat", "Access the cat"); defaultDescriptions.put("pets.dog", "Dog your data"); defaultDescriptions.put("pony", "The magic of friendship"); bootstrap.setMessageSource(new MapPropertySource("messages.properties", defaultDescriptions)); bootstrap.setMessagePropertyNameTemplate("%s"); bootstrap.setNonDefaultUserGroups(Collections.singleton("pets.cat")); bootstrap.setDefaultUserGroups(Collections.singleton("pets.dog")); Map<String, String> groups = new HashMap<>(); groups.put("pony", ""); bootstrap.setGroups(groups); bootstrap.afterPropertiesSet(); List<ScimGroup> bootstrappedGroups = gDB.retrieveAll(); assertThat(bootstrappedGroups, PredicateMatcher.<ScimGroup>has(group -> "pets.cat".equals(group.getDisplayName()) && "Access the cat".equals(group.getDescription()))); assertThat(bootstrappedGroups, PredicateMatcher.<ScimGroup>has(group -> "pets.dog".equals(group.getDisplayName()) && "Dog your data".equals(group.getDescription()))); assertThat(bootstrappedGroups, PredicateMatcher.<ScimGroup>has(group -> "pony".equals(group.getDisplayName()) && "The magic of friendship".equals(group.getDescription()))); } @Test public void prefersNonBlankYmlOverMessagesProperties() throws Exception { // set up default groups HashMap<String, Object> defaults = new HashMap<>(); defaults.put("records.read", ""); defaults.put("pets.cat", "Access the cat"); defaults.put("pets.dog", "Dog your data"); HashMap<String, Object> nonDefaultUserGroups = new HashMap<>(); nonDefaultUserGroups.put("water.drink", "hint"); bootstrap.setMessageSource(new MapPropertySource("messages.properties", defaults)); bootstrap.setMessagePropertyNameTemplate("%s"); bootstrap.setNonDefaultUserGroups(nonDefaultUserGroups.keySet()); bootstrap.setDefaultUserGroups(defaults.keySet()); Map<String, String> groups = new HashMap<>(); groups.put("print", "Access the network printer"); groups.put("records.read", "Read important data"); groups.put("pets.cat", "Pet the cat"); groups.put("pets.dog", null); groups.put("fish.nemo", null); groups.put("water.drink", "Drink the water"); // set up configured groups bootstrap.setGroups(groups); bootstrap.afterPropertiesSet(); List<ScimGroup> bootstrappedGroups = gDB.retrieveAll(); // print: only specified in the configured groups, so it should get its description from there assertThat(bootstrappedGroups, PredicateMatcher.<ScimGroup>has(group -> "print".equals(group.getDisplayName()) && "Access the network printer".equals(group.getDescription()))); // records.read: exists in the message property source but should get its description from configuration assertThat(bootstrappedGroups, PredicateMatcher.<ScimGroup>has(group -> "records.read".equals(group.getDisplayName()) && "Read important data".equals(group.getDescription()))); // pets.cat: read: exists in the message property source but should get its description from configuration assertThat(bootstrappedGroups, PredicateMatcher.<ScimGroup>has(group -> "pets.cat".equals(group.getDisplayName()) && "Pet the cat".equals(group.getDescription()))); // pets.dog: specified in configuration with no description, so it should retain the default description assertThat(bootstrappedGroups, PredicateMatcher.<ScimGroup>has(group -> "pets.dog".equals(group.getDisplayName()) && "Dog your data".equals(group.getDescription()))); // fish.nemo: never gets a description assertThat(bootstrappedGroups, PredicateMatcher.<ScimGroup>has(group -> "fish.nemo".equals(group.getDisplayName()) && group.getDescription() == null)); assertThat(bootstrappedGroups, PredicateMatcher.<ScimGroup>has(group -> "water.drink".equals(group.getDisplayName()) && "Drink the water".equals(group.getDescription()))); } }