package org.picketlink.test.idm.other.shane; import org.junit.Test; import org.picketlink.idm.IdentityManager; import org.picketlink.idm.PartitionManager; import org.picketlink.idm.PermissionManager; import org.picketlink.idm.config.IdentityConfigurationBuilder; import org.picketlink.idm.credential.Credentials; import org.picketlink.idm.credential.Password; import org.picketlink.idm.credential.UsernamePasswordCredentials; import org.picketlink.idm.internal.DefaultPartitionManager; import org.picketlink.idm.jpa.internal.JPAIdentityStore; import org.picketlink.idm.model.Attribute; import org.picketlink.idm.model.basic.Realm; import org.picketlink.idm.permission.IdentityPermission; import org.picketlink.idm.permission.Permission; import org.picketlink.idm.spi.ContextInitializer; import org.picketlink.idm.spi.IdentityContext; import org.picketlink.idm.spi.IdentityStore; import org.picketlink.test.idm.other.shane.model.scenario1.Role; import org.picketlink.test.idm.other.shane.model.scenario1.User; import org.picketlink.test.idm.other.shane.model.scenario1.entity.City; import org.picketlink.test.idm.other.shane.model.scenario1.entity.Country; import org.picketlink.test.idm.other.shane.model.scenario1.entity.EmployeeContract; import org.picketlink.test.idm.other.shane.model.scenario1.entity.PartitionAttribute; import org.picketlink.test.idm.other.shane.model.scenario1.entity.PasswordHash; import org.picketlink.test.idm.other.shane.model.scenario1.entity.RoleDetail; import org.picketlink.test.idm.other.shane.model.scenario1.entity.State; import org.picketlink.test.idm.other.shane.model.scenario1.entity.StreetType; import org.picketlink.test.idm.other.shane.model.scenario1.entity.UserAddress; import org.picketlink.test.idm.other.shane.model.scenario2.entity.Customer; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Random; /** * Shane's broad-spectrum test suite - PLEASE DO NOT TOUCH!! * * @author Shane Bryzak */ public class ShanesBigSanityCheckTestCase { /** * This scenario exercises a variety of use cases against a relational database (JPA) identity store */ @Test public void testScenario1() throws InterruptedException { EntityManagerFactory emf = Persistence.createEntityManagerFactory("shanes-test-suite-scenario1-pu"); final EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder(); builder.named("default") .stores() .jpa() .mappedEntity(org.picketlink.test.idm.other.shane.model.scenario1.entity.AccountLogin.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.IdentityObject.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.IdentityObjectAttribute.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.IdentityTextAttribute.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.Partition.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.PartitionAttribute.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.Relationship.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.RelationshipAttribute.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.RelationshipIdentity.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.RoleDetail.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.UserAddress.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.UserContact.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.UserDetail.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.UserEmail.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.EmployeeContract.class, org.picketlink.test.idm.other.shane.model.scenario1.entity.PasswordHash.class) .addContextInitializer(new ContextInitializer() { @Override public void initContextForStore(IdentityContext context, IdentityStore<?> store) { context.setParameter(JPAIdentityStore.INVOCATION_CTX_ENTITY_MANAGER, em); } }) .addCredentialHandler(UserPasswordCredentialHandler.class) .supportAllFeatures(); PartitionManager partitionManager = new DefaultPartitionManager(builder.buildAll()); // Create a realm with some attributes Realm r = new Realm(Realm.DEFAULT_REALM); r.setAttribute(new Attribute<String>("foo", "bar")); partitionManager.add(r, "default"); // Assert that the attribute exclude was set r = partitionManager.<Realm>getPartition(Realm.class, Realm.DEFAULT_REALM); assert "bar".equals(r.getAttribute("foo").getValue()); PartitionAttribute pa = em.createQuery( "select pa from PartitionAttribute pa where pa.partition.partitionId = :id and pa.attributeName = :attributeName", PartitionAttribute.class) .setParameter("id", r.getId()) .setParameter("attributeName", "foo") .getSingleResult(); // Assert that the attribute exclude is stored as a String // assert "bar".equals(pa.getAttributeValue()); attribute exclude is serialized // Update the attribute exclude r.setAttribute(new Attribute<String>("foo", "222")); partitionManager.update(r); // Lookup the realm again r = partitionManager.<Realm>getPartition(Realm.class, Realm.DEFAULT_REALM); // Assert that the attribute exclude was updated assert "222".equals(r.getAttribute("foo").getValue()); // Delete the attribute r.removeAttribute("foo"); partitionManager.update(r); r = partitionManager.<Realm>getPartition(Realm.class, Realm.DEFAULT_REALM); // Confirm the attribute exclude was deleted assert r.getAttribute("foo") == null; // Create a new user User u = new User(); u.setFirstName("John"); u.setLastName("Smith"); u.setLoginName("jsmith"); // Create an identity manager for the default partition IdentityManager identityManager = partitionManager.createIdentityManager(); // Add the user identityManager.add(u); // Confirm that the identifier has been set assert u.getId() != null; // Lookup the user u = identityManager.lookupIdentityById(User.class, u.getId()); // Confirm the properties have been set correctly assert "John".equals(u.getFirstName()); assert "Smith".equals(u.getLastName()); assert "jsmith".equals(u.getLoginName()); // Set an attribute and update the user u.setAttribute(new Attribute<String>("SSN", "123-456-7890")); identityManager.update(u); // Lookup the user again u = identityManager.lookupIdentityById(User.class, u.getId()); // Confirm the attribute was correctly set assert "123-456-7890".equals(u.<String>getAttribute("SSN").getValue()); // // Lookup the attribute record in the database // IdentityTextAttribute attr = em.createIdentityQuery( // "select a from IdentityTextAttribute a where a.identity.id = :id and a.attributeName = :attributeName", // IdentityTextAttribute.class) // .setParameter("id", u.getId()) // .setParameter("attributeName", "SSN") // .getSingleResult(); // // // Confirm the attribute string exclude is stored as text // assert "123-456-7890".equals(attr.getAttributeValue()); // Create a random size byte array at least 512 bytes in size and populate it Random rnd = new Random(System.currentTimeMillis()); final byte[] binaryData = new byte[512 + rnd.nextInt(50000)]; rnd.nextBytes(binaryData); // Add another attribute containing binary data u.setAttribute(new Attribute<byte[]>("profilePhoto", binaryData)); // Update the user identityManager.update(u); // Lookup the user again u = identityManager.lookupIdentityById(User.class, u.getId()); // Confirm the binary exclude was correctly set assert Arrays.equals(binaryData, u.<byte[]>getAttribute("profilePhoto").getValue()); // Confirm that the binary exclude was persisted in the correct table // assert !em.createIdentityQuery( // "select a from IdentityObjectAttribute a where a.identity.id = :id and a.attributeName = :attributeName", // IdentityObjectAttribute.class) // .setParameter("id", u.getId()) // .setParameter("attributeName", "profilePhoto") // .getResultList().isEmpty(); // Create some default lookup data in the database Country country = new Country(); country.setName("Australia"); State state = new State(); state.setCountry(country); state.setName("QLD"); City city = new City(); city.setState(state); city.setName("Brisbane"); StreetType streetType = new StreetType(); streetType.setDescription("Street"); em.persist(country); em.persist(state); em.persist(city); em.persist(streetType); // Create a UserAddress instance and assign it to the userberkshire UserAddress addr = new UserAddress(); addr.setUnitNumber("15B"); addr.setStreetNumber("123"); addr.setStreetName("Main"); addr.setStreetType(streetType); addr.setCity(city); List<UserAddress> addresses = new ArrayList<UserAddress>(); addresses.add(addr); u.setAddresses(addresses); // Update the user identityManager.update(u); // Lookup the user again u = identityManager.lookupIdentityById(User.class, u.getId()); // Confirm the address was created, and details are correct assert u.getAddresses().size() == 1; addr = u.getAddresses().get(0); assert "15B".equals(addr.getUnitNumber()); assert "123".equals(addr.getStreetNumber()); // Create another address addr = new UserAddress(); addr.setStreetNumber("16"); addr.setStreetName("Elizabeth"); addr.setStreetType(streetType); addr.setCity(city); u.getAddresses().add(addr); // Update the user identityManager.update(u); // Lookup the user again u = identityManager.lookupIdentityById(User.class, u.getId()); // Confirm the second address was persisted assert u.getAddresses().size() == 2; // Delete the first address, and update the details of the second one Iterator<UserAddress> i = u.getAddresses().iterator(); while (i.hasNext()) { addr = i.next(); if ("Main".equals(addr.getStreetName())) { i.remove(); } else { addr.setStreetNumber("18"); } } // Update the user identityManager.update(u); // Lookup the user again u = identityManager.lookupIdentityById(User.class, u.getId()); // Confirm there is only one address now assert u.getAddresses().size() == 1; // Confirm that the address details were updated assert "18".equals(u.getAddresses().get(0).getStreetNumber()); // Confirm that no employee contract is currently set assert u.getEmployeeContract() == null; // Create an employee contract and assign it to the user EmployeeContract contract = new EmployeeContract(); Date now = new Date(); contract.setSignedDate(now); // Generate some more random binary data to represent the scanned contract document final byte[] documentData = new byte[512 + rnd.nextInt(50000)]; rnd.nextBytes(documentData); contract.setDocument(documentData); // Assign the employee contract to the user and then update the user u.setEmployeeContract(contract); identityManager.update(u); // Lookup the user again u = identityManager.lookupIdentityById(User.class, u.getId()); // Confirm that the employee contract was set assert u.getEmployeeContract() != null; // Confirm that the date was set correctly, and the document data is correct assert now.equals(u.getEmployeeContract().getSignedDate()); assert Arrays.equals(documentData, u.getEmployeeContract().getDocument()); // Confirm that the employee contract was persisted in the correct table assert !em.createQuery( "select c from EmployeeContract c where c.identity.id = :id", EmployeeContract.class) .setParameter("id", u.getId()) .getResultList().isEmpty(); // Now remove the contract and then update the user u.setEmployeeContract(null); identityManager.update(u); // Lookup the user again u = identityManager.lookupIdentityById(User.class, u.getId()); // Confirm that the employee contract is null assert u.getEmployeeContract() == null; // Confirm that the record was deleted from the database assert em.createQuery( "select c from EmployeeContract c where c.identity.id = :id", EmployeeContract.class) .setParameter("id", u.getId()) .getResultList().isEmpty(); // Assign a password to the user Password pwd = new Password("password1234"); identityManager.updateCredential(u, pwd); // Confirm that the user can authenticate using their password Credentials creds = new UsernamePasswordCredentials("jsmith", pwd); identityManager.validateCredentials(creds); assert Credentials.Status.VALID.equals(creds.getStatus()); // Confirm that the password was persisted in the correct table assert !em.createQuery( "select h from PasswordHash h where h.identity.id = :id", PasswordHash.class) .setParameter("id", u.getId()) .getResultList().isEmpty(); // Assign a new password that doesn't come into effect until tomorrow Date tomorrow = new Date(System.currentTimeMillis() + (24 * 60 * 60 * 1000)); Password newPwd = new Password("newpassword1234"); identityManager.updateCredential(u, newPwd, tomorrow, null); /** * COMMENTED BECAUSE CREDENTIALS HISTORY IS NOT KEPT ANYMORE * // Confirm that the old password still validates * creds = new UsernamePasswordCredentials("jsmith", pwd); * identityManager.validateCredentials(creds); * assert Credentials.Status.VALID.equals(creds.getStatus()); */ // Confirm that the new password doesn't validate yet creds = new UsernamePasswordCredentials("jsmith", newPwd); identityManager.validateCredentials(creds); assert Credentials.Status.INVALID.equals(creds.getStatus()); // Create a new role and add it Role role = new Role("employee"); identityManager.add(role); // Lookup the role role = identityManager.lookupIdentityById(Role.class, role.getId()); // Confirm the role name was correctly set assert "employee".equals(role.getName()); // Confirm that a RoleDetail entity was created List<RoleDetail> id = em.createQuery( "select r from RoleDetail r where r.roleName = ?", RoleDetail.class) .setParameter(1, role.getName()) .getResultList(); assert !id.isEmpty(); em.getTransaction().commit(); } @Test public void testScenario2() throws InterruptedException { EntityManagerFactory emf = Persistence.createEntityManagerFactory("shanes-test-suite-scenario2-pu"); final EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder(); builder.named("default") .stores() .jpa() .mappedEntity(org.picketlink.test.idm.other.shane.model.scenario1.entity.AccountLogin.class, org.picketlink.test.idm.other.shane.model.scenario2.entity.IdentityObject.class, org.picketlink.test.idm.other.shane.model.scenario2.entity.IdentityObjectAttribute.class, org.picketlink.test.idm.other.shane.model.scenario2.entity.Partition.class, org.picketlink.test.idm.other.shane.model.scenario2.entity.PartitionAttribute.class, org.picketlink.test.idm.other.shane.model.scenario2.entity.ResourcePermission.class, org.picketlink.test.idm.other.shane.model.scenario2.entity.UserDetail.class) .addContextInitializer(new ContextInitializer() { @Override public void initContextForStore(IdentityContext context, IdentityStore<?> store) { context.setParameter(JPAIdentityStore.INVOCATION_CTX_ENTITY_MANAGER, em); } }) .addCredentialHandler(UserPasswordCredentialHandler.class) .supportType(org.picketlink.test.idm.other.shane.model.scenario2.User.class, Realm.class) .supportPermissions(true); PartitionManager partitionManager = new DefaultPartitionManager(builder.buildAll()); // Create a realm with some attributes Realm r = new Realm(Realm.DEFAULT_REALM); r.setAttribute(new Attribute<String>("foo", "bar")); partitionManager.add(r, "default"); // Create a new user org.picketlink.test.idm.other.shane.model.scenario2.User u = new org.picketlink.test.idm.other.shane.model.scenario2.User(); u.setLoginName("shane"); // Create an identity manager for the default partition IdentityManager identityManager = partitionManager.createIdentityManager(); // Add the user identityManager.add(u); // Lookup the user u = identityManager.lookupIdentityById(org.picketlink.test.idm.other.shane.model.scenario2.User.class, u.getId()); // Create some sample customer objects and persist them Customer c1 = new Customer(); c1.setName("Acme"); em.persist(c1); Customer c2 = new Customer(); c2.setName("BuyNLarge"); em.persist(c2); // Create a PermissionManager PermissionManager pm = partitionManager.createPermissionManager(); // Grant the 'READ' permission for Customer c1 to the user we created pm.grantPermission(u, c1, Customer.PERMISSION_READ); // Confirm that the permission was created assert !pm.listPermissions(c1).isEmpty(); // Clear all permissions for Customer c1 pm.clearPermissions(c1); assert pm.listPermissions(c1).isEmpty(); // Grant the 'UPDATE' permission for Customer c1 to the user we created pm.grantPermission(u, c1, Customer.PERMISSION_UPDATE); // Confirm that the permission can by looked up via the resource reference assert !pm.listPermissions(c1, Customer.PERMISSION_UPDATE).isEmpty(); // Also assert there was only one permission created assert pm.listPermissions(c1).size() == 1; // Lookup the permission object Permission p = pm.listPermissions(c1).get(0); // Assert the permission properties are correctly set assert p.getResource().equals(c1); assert p instanceof IdentityPermission; assert ((IdentityPermission) p).getAssignee().equals(u); assert Customer.PERMISSION_UPDATE.equals(p.getOperation()); // Grant the 'DELETE' permission for Customer c1 to the user we created pm.grantPermission(u, c1, Customer.PERMISSION_DELETE); // Confirm that the permission exists assert !pm.listPermissions(c1, Customer.PERMISSION_DELETE).isEmpty(); } }