private IdentityStore<?> getContextualStoreForFeature(IdentityStoreInvocationContext ctx, Feature feature) { String realm = (ctx.getRealm() != null) ? ctx.getRealm().getName() : Realm.DEFAULT_REALM; if (!realmStores.containsKey(realm)) { throw new SecurityException("The specified realm '" + realm + "' has not been configured."); } IdentityStoreConfiguration config = null; Map<Feature,IdentityStoreConfiguration> featureToStoreMap = realmStores.get(realm); if (featureToStoreMap.containsKey(feature)) { config = featureToStoreMap.get(feature); } else if (featureToStoreMap.containsKey(Feature.all)) { config = featureToStoreMap.get(Feature.all); } else { throw new UnsupportedOperationException("The requested identity management feature [" + feature.toString() + "] has not been configured."); } IdentityStore<?> store = storeFactory.createIdentityStore(config, ctx); getContextFactory().initContextForStore(ctx, store); return store; }
@Override public void add(IdentityType identityType) { Feature feature; IdentityStoreInvocationContext ctx = createContext(); if (User.class.isInstance(identityType)) { feature = Feature.createUser; } else if (Group.class.isInstance(identityType)) { if (ctx.getRealm() != null && ctx.getTier() != null) { throw new IllegalStateException("Ambiguous context state - Group may only be managed in either the " + "scope of a Realm or a Tier, however both have been set."); } feature = Feature.createGroup; } else if (Role.class.isInstance(identityType)) { if (ctx.getRealm() != null && ctx.getTier() != null) { throw new IllegalStateException("Ambiguous context state - Role may only be managed in either the " + "scope of a Realm or a Tier, however both have been set."); } feature = Feature.createRole; } else if (Agent.class.isInstance(identityType)) { feature = Feature.createAgent; } else if (Relationship.class.isInstance(identityType)) { feature = Feature.createAgent; } else { throw new IllegalArgumentException("Unsupported IdentityType:" + identityType.getClass().getName()); } getContextualStoreForFeature(ctx, feature).add(identityType); }
@Override public void remove(IdentityType identityType) { Feature feature; IdentityStoreInvocationContext ctx = createContext(); if (User.class.isInstance(identityType)) { feature = Feature.deleteUser; } else if (Agent.class.isInstance(identityType)) { feature = Feature.deleteAgent; } else if (Group.class.isInstance(identityType)) { if (ctx.getRealm() != null && ctx.getTier() != null) { throw new IllegalStateException("Ambiguous context state - Group may only be managed in either the " + "scope of a Realm or a Tier, however both have been set."); } feature = Feature.deleteGroup; } else if (Role.class.isInstance(identityType)) { if (ctx.getRealm() != null && ctx.getTier() != null) { throw new IllegalStateException("Ambiguous context state - Role may only be managed in either the " + "scope of a Realm or a Tier, however both have been set."); } feature = Feature.deleteRole; } else { throw new IllegalArgumentException("Unsupported IdentityType"); } getContextualStoreForFeature(ctx, feature).remove(identityType); }
@Override public Group getGroup(String groupName, Group parent) { IdentityStoreInvocationContext ctx = createContext(); if (ctx.getRealm() != null && ctx.getTier() != null) { throw new IllegalStateException("Ambiguous context state - Group may only be managed in either the " + "scope of a Realm or a Tier, however both have been set."); } return getContextualStoreForFeature(ctx, Feature.readGroup).getGroup(groupName, parent); }
@Override public void update(IdentityType identityType) { Feature feature; IdentityStoreInvocationContext ctx = createContext(); if (User.class.isInstance(identityType)) { feature = Feature.updateUser; } else if (Agent.class.isInstance(identityType)) { feature = Feature.updateAgent; } else if (Group.class.isInstance(identityType)) { if (ctx.getRealm() != null && ctx.getTier() != null) { throw new IllegalStateException("Ambiguous context state - Group may only be managed in either the " + "scope of a Realm or a Tier, however both have been set."); } feature = Feature.updateGroup; } else if (Role.class.isInstance(identityType)) { if (ctx.getRealm() != null && ctx.getTier() != null) { throw new IllegalStateException("Ambiguous context state - Role may only be managed in either the " + "scope of a Realm or a Tier, however both have been set."); } feature = Feature.updateRole; } else { throw new IllegalArgumentException("Unsupported IdentityType"); } getContextualStoreForFeature(createContext(), feature).update(identityType); }
@Override public Group getGroup(String groupId) { IdentityStoreInvocationContext ctx = createContext(); if (ctx.getRealm() != null && ctx.getTier() != null) { throw new IllegalStateException("Ambiguous context state - Group may only be managed in either the " + "scope of a Realm or a Tier, however both have been set."); } return getContextualStoreForFeature(ctx, Feature.readGroup).getGroup(groupId); }
@Override public Role getRole(String name) { IdentityStoreInvocationContext ctx = createContext(); if (ctx.getRealm() != null && ctx.getTier() != null) { throw new IllegalStateException("Ambiguous context state - Role may only be managed in either the " + "scope of a Realm or a Tier, however both have been set."); } return getContextualStoreForFeature(ctx, Feature.readRole).getRole(name); }
@Override public User getUser(String id) { if (id == null) { return null; } // Check the cache first User user = getContext().getCache().lookupUser(context.getRealm(), id); // If the cache doesn't have a reference to the User, we have to look up it's identity object // and create a User instance based on it if (user == null) { DefaultIdentityQuery<User> defaultIdentityQuery = new DefaultIdentityQuery(User.class, this); defaultIdentityQuery.setParameter(User.ID, id); List<User> resultList = defaultIdentityQuery.getResultList(); if (!resultList.isEmpty()) { user = resultList.get(0); } getContext().getCache().putUser(context.getRealm(), user); } return user; }
@Override public <T extends IdentityType> List<T> fetchQueryResults(IdentityQuery<T> identityQuery) { List<T> result = new ArrayList<T>(); try { EntityManager em = getEntityManager(); JPACriteriaQueryBuilder criteriaBuilder = new JPACriteriaQueryBuilder(this, identityQuery); List<Predicate> predicates = criteriaBuilder.getPredicates(); CriteriaQuery<?> criteria = criteriaBuilder.getCriteria(); criteria.where(predicates.toArray(new Predicate[predicates.size()])); List<?> queryResult = em.createQuery(criteria).getResultList(); for (Object identity : queryResult) { String discriminator = getConfig().getModelProperty(PROPERTY_IDENTITY_DISCRIMINATOR).getValue(identity) .toString(); IdentityTypeHandler<? extends IdentityType> identityTypeManager = getConfig().getIdentityTypeStores().get( discriminator); T identityType = (T) identityTypeManager.createIdentityType(getContext().getRealm(), identity, this); configurePartition(getContext().getRealm(), identity, identityType); populateAttributes(identityType, identity); result.add(identityType); } } catch (Exception e) { throw new IdentityManagementException("Error executing query.", e); } return result; }
@Override public Group getGroup(String groupId) { if (groupId == null) { return null; } // Check the cache first Realm partition = context.getRealm(); Group group = getContext().getCache().lookupGroup(partition, groupId); if (group == null) { DefaultIdentityQuery<Group> defaultIdentityQuery = new DefaultIdentityQuery(Group.class, this); defaultIdentityQuery.setParameter(Group.NAME, groupId); List<Group> resultList = defaultIdentityQuery.getResultList(); if (!resultList.isEmpty()) { group = resultList.get(0); } getContext().getCache().putGroup(partition, group); } return group; }
@Override public void update(IdentityType identityType) { checkInvalidIdentityType(identityType); IdentityTypeHandler<IdentityType> identityTypeManager = getConfig().getIdentityTypeManager(identityType.getClass()); Object identity = getIdentityObject(identityType); identityTypeManager.populateIdentityInstance(getContext().getRealm(), identity, identityType, this); updateAttributes(identityType, identity); EntityManager em = getEntityManager(); em.merge(identity); em.flush(); AbstractBaseEvent event = identityTypeManager.raiseUpdatedEvent(identityType, this); event.getContext().setValue(EVENT_CONTEXT_USER_ENTITY, identity); getContext().getEventBridge().raiseEvent(event); }
@Override public Role getRole(String name) { if (name == null) { return null; } // Check the cache first Realm partition = context.getRealm(); Role role = getContext().getCache().lookupRole(partition, name); // If the cache doesn't have a reference to the Role, we have to look up it's identity object // and create a Role instance based on it if (role == null) { DefaultIdentityQuery<Role> defaultIdentityQuery = new DefaultIdentityQuery(Role.class, this); defaultIdentityQuery.setParameter(Role.NAME, name); List<Role> resultList = defaultIdentityQuery.getResultList(); if (!resultList.isEmpty()) { role = resultList.get(0); } getContext().getCache().putRole(partition, role); } return role; }
@Override public Agent getAgent(String id) { if (id == null) { return null; } // Check the cache first Realm partition = context.getRealm(); Agent agent = getContext().getCache().lookupAgent(partition, id); // If the cache doesn't have a reference to the User, we have to look up it's identity object // and create a User instance based on it if (agent == null) { DefaultIdentityQuery<Agent> defaultIdentityQuery = new DefaultIdentityQuery(Agent.class, this); defaultIdentityQuery.setParameter(Agent.ID, id); List<Agent> resultList = defaultIdentityQuery.getResultList(); if (!resultList.isEmpty()) { agent = resultList.get(0); } else { agent = getUser(id); } getContext().getCache().putAgent(partition, agent); } return agent; }
@Override public void add(IdentityType identityType) { checkInvalidIdentityType(identityType); if (lookupIdentityObjectById(identityType) != null) { throw new IdentityManagementException("IdentityType already exists."); } try { IdentityTypeHandler<IdentityType> identityTypeManager = getConfig().getIdentityTypeManager(identityType.getClass()); Object identity = identityTypeManager.createIdentityInstance(getContext().getRealm(), identityType, this); EntityManager em = getEntityManager(); em.persist(identity); em.flush(); updateAttributes(identityType, identity); AbstractBaseEvent event = identityTypeManager.raiseCreatedEvent(identityType, this); event.getContext().setValue(EVENT_CONTEXT_USER_ENTITY, identity); getContext().getEventBridge().raiseEvent(event); } catch (Exception ex) { throw new IdentityManagementException("Exception while creating IdentityType [" + identityType + "].", ex); } }