Commit 68cf3a4b authored by michael.simon's avatar michael.simon
Browse files

Refactor service and dao layers

parent 1d1d474f
......@@ -39,4 +39,6 @@ public interface BaseDao<T extends BaseEntity<PK>, PK extends Serializable> {
T findByIdWithAttrs(PK id, String... attrs);
void refresh(T entity);
}
......@@ -11,6 +11,7 @@
package edu.kit.scc.webreg.dao;
import java.util.List;
import java.util.Set;
import edu.kit.scc.webreg.entity.GroupEntity;
import edu.kit.scc.webreg.entity.RoleEntity;
......@@ -46,6 +47,6 @@ public interface RoleDao extends BaseDao<RoleEntity, Long> {
RoleGroupEntity findRoleGroupEntity(GroupEntity group, RoleEntity role);
List<RoleEntity> findByGroups(List<Long> groups);
List<RoleEntity> findByGroups(Set<GroupEntity> groups);
}
......@@ -70,6 +70,11 @@ public abstract class JpaBaseDao<T extends BaseEntity<PK>, PK extends Serializab
return em.merge(entity);
}
@Override
public void refresh(T entity) {
em.refresh(entity);
}
@SuppressWarnings("unchecked")
@Override
public List<T> findAll() {
......
......@@ -11,6 +11,7 @@
package edu.kit.scc.webreg.dao.jpa;
import java.util.List;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
......@@ -83,8 +84,8 @@ public class JpaRoleDao extends JpaBaseDao<RoleEntity, Long> implements RoleDao
@SuppressWarnings("unchecked")
@Override
public List<RoleEntity> findByGroups(List<Long> groups) {
return em.createQuery("select r.role from RoleGroupEntity r where r.group.id in (:groups)")
public List<RoleEntity> findByGroups(Set<GroupEntity> groups) {
return em.createQuery("select r.role from RoleGroupEntity r where r.group in (:groups)")
.setParameter("groups", groups).getResultList();
}
......
......@@ -155,7 +155,7 @@ public class KnowledgeSessionServiceImpl implements KnowledgeSessionService {
RegistryEntity registry, String executor, Boolean withCache)
throws MisconfiguredServiceException {
user = userDao.findById(user.getId());
user = userDao.merge(user);
if (withCache) {
service = serviceDao.findById(service.getId());
......
......@@ -22,7 +22,6 @@ import org.slf4j.LoggerFactory;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.exc.UserUpdateException;
import edu.kit.scc.webreg.service.UserService;
import edu.kit.scc.webreg.service.UserUpdateService;
public class UpdateAllUserFromIdp extends AbstractExecutableJob {
......@@ -64,7 +63,6 @@ public class UpdateAllUserFromIdp extends AbstractExecutableJob {
InitialContext ic = new InitialContext();
UserService userService = (UserService) ic.lookup("global/bwreg/bwreg-service/UserServiceImpl!edu.kit.scc.webreg.service.UserService");
UserUpdateService userUpdateService = (UserUpdateService) ic.lookup("global/bwreg/bwreg-service/UserUpdateServiceImpl!edu.kit.scc.webreg.service.UserUpdateService");
List<UserEntity> userList = userService.findOrderByFailedUpdateWithLimit(new Date(System.currentTimeMillis() - lastUpdate), limit);
......@@ -79,7 +77,7 @@ public class UpdateAllUserFromIdp extends AbstractExecutableJob {
for (UserEntity user : userList) {
try {
logger.info("Updating user {}", user.getEppn());
userUpdateService.updateUserFromIdp(user);
userService.updateUserFromIdp(user);
} catch (UserUpdateException e) {
logger.warn("Could not update user {}: {}", user.getEppn(), e);
}
......
......@@ -21,6 +21,8 @@ public interface BaseService<T extends BaseEntity<PK>, PK extends Serializable>
T createNew();
T merge(T entity);
T save(T entity);
void delete(T entity);
......
......@@ -11,14 +11,9 @@
package edu.kit.scc.webreg.service;
import java.util.List;
import java.util.Map;
import java.util.Set;
import edu.kit.scc.webreg.audit.Auditor;
import edu.kit.scc.webreg.entity.GroupEntity;
import edu.kit.scc.webreg.entity.HomeOrgGroupEntity;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.exc.UserUpdateException;
public interface HomeOrgGroupService extends BaseService<HomeOrgGroupEntity, Long> {
......@@ -28,10 +23,6 @@ public interface HomeOrgGroupService extends BaseService<HomeOrgGroupEntity, Lon
HomeOrgGroupEntity findWithUsers(Long id);
Set<GroupEntity> updateGroupsForUser(UserEntity user,
Map<String, List<Object>> attributeMap, Auditor auditor)
throws UserUpdateException;
HomeOrgGroupEntity persistWithServiceFlags(HomeOrgGroupEntity entity);
}
......@@ -11,7 +11,9 @@
package edu.kit.scc.webreg.service;
import java.util.List;
import java.util.Set;
import edu.kit.scc.webreg.entity.GroupEntity;
import edu.kit.scc.webreg.entity.RoleEntity;
import edu.kit.scc.webreg.entity.UserEntity;
......@@ -33,6 +35,6 @@ public interface RoleService extends BaseService<RoleEntity, Long> {
Boolean checkAdminUserInRole(Long userId, String roleName);
List<RoleEntity> findByGroups(List<Long> groups);
List<RoleEntity> findByGroups(Set<GroupEntity> groups);
}
......@@ -16,6 +16,7 @@ import java.util.Map;
import edu.kit.scc.webreg.audit.Auditor;
import edu.kit.scc.webreg.entity.GroupEntity;
import edu.kit.scc.webreg.entity.ServiceEntity;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.exc.UserUpdateException;
......@@ -46,4 +47,13 @@ public interface UserService extends BaseService<UserEntity, Long> {
List<UserEntity> findGenericStoreKeyWithLimit(String key, Integer limit);
List<UserEntity> findOrderByFailedUpdateWithLimit(Date date, Integer limit);
UserEntity updateUserFromIdp(UserEntity user) throws UserUpdateException;
UserEntity updateUserFromIdp(UserEntity user, ServiceEntity service)
throws UserUpdateException;
UserEntity updateUserFromAttribute(UserEntity user,
Map<String, List<Object>> attributeMap, String executor)
throws UserUpdateException;
}
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.service;
import java.util.List;
import java.util.Map;
import org.opensaml.saml2.core.Assertion;
import edu.kit.scc.webreg.entity.ServiceEntity;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.exc.UserUpdateException;
public interface UserUpdateService {
UserEntity updateUserFromIdp(UserEntity user) throws UserUpdateException;
UserEntity updateUser(UserEntity user,
Map<String, List<Object>> attributeMap, String executor,
ServiceEntity service) throws UserUpdateException;
UserEntity updateUser(UserEntity user, Assertion assertion,
String executor, ServiceEntity service) throws UserUpdateException;
UserEntity updateUserFromIdp(UserEntity user, ServiceEntity service)
throws UserUpdateException;
UserEntity updateUser(UserEntity user,
Map<String, List<Object>> attributeMap, String executor)
throws UserUpdateException;
}
......@@ -35,6 +35,11 @@ public abstract class BaseServiceImpl<T extends BaseEntity<PK>, PK extends Seria
return getDao().persist(entity);
}
@Override
public T merge(T entity) {
return getDao().merge(entity);
}
@Override
public void delete(T entity) {
getDao().delete(entity);
......
......@@ -10,366 +10,25 @@
******************************************************************************/
package edu.kit.scc.webreg.service.impl;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ejb.Stateless;
import javax.inject.Inject;
import org.slf4j.Logger;
import edu.kit.scc.webreg.audit.Auditor;
import edu.kit.scc.webreg.dao.BaseDao;
import edu.kit.scc.webreg.dao.GroupDao;
import edu.kit.scc.webreg.dao.HomeOrgGroupDao;
import edu.kit.scc.webreg.dao.ServiceGroupFlagDao;
import edu.kit.scc.webreg.entity.AuditStatus;
import edu.kit.scc.webreg.entity.EventType;
import edu.kit.scc.webreg.entity.GroupEntity;
import edu.kit.scc.webreg.entity.HomeOrgGroupEntity;
import edu.kit.scc.webreg.entity.ServiceBasedGroupEntity;
import edu.kit.scc.webreg.entity.ServiceGroupFlagEntity;
import edu.kit.scc.webreg.entity.ServiceGroupStatus;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.entity.UserGroupEntity;
import edu.kit.scc.webreg.event.EventSubmitter;
import edu.kit.scc.webreg.event.MultipleGroupEvent;
import edu.kit.scc.webreg.exc.EventSubmitException;
import edu.kit.scc.webreg.exc.UserUpdateException;
import edu.kit.scc.webreg.service.GroupServiceHook;
import edu.kit.scc.webreg.service.HomeOrgGroupService;
import edu.kit.scc.webreg.service.SerialService;
@Stateless
public class HomeOrgGroupServiceImpl extends BaseServiceImpl<HomeOrgGroupEntity, Long> implements HomeOrgGroupService {
private static final long serialVersionUID = 1L;
@Inject
private Logger logger;
@Inject
private HookManager hookManager;
@Inject
private HomeOrgGroupDao dao;
@Inject
private GroupDao groupDao;
@Inject
private ServiceGroupFlagDao groupFlagDao;
@Inject
private AttributeMapHelper attrHelper;
@Inject
private SerialService serialService;
@Inject
private EventSubmitter eventSubmitter;
@Override
public Set<GroupEntity> updateGroupsForUser(UserEntity user, Map<String, List<Object>> attributeMap, Auditor auditor)
throws UserUpdateException {
HashSet<GroupEntity> changedGroups = new HashSet<GroupEntity>();
changedGroups.addAll(updatePrimary(user, attributeMap, auditor));
changedGroups.addAll(updateSecondary(user, attributeMap, auditor));
// Also add parent groups, to reflect changes
HashSet<GroupEntity> allChangedGroups = new HashSet<GroupEntity>(changedGroups.size());
for (GroupEntity group : changedGroups) {
allChangedGroups.add(group);
if (group.getParents() != null) {
for (GroupEntity parent : group.getParents()) {
logger.debug("Adding parent group to changed groups: {}", parent.getName());
allChangedGroups.add(parent);
}
}
}
for (GroupEntity group : allChangedGroups) {
if (group instanceof ServiceBasedGroupEntity) {
List<ServiceGroupFlagEntity> groupFlagList = groupFlagDao.findByGroup((ServiceBasedGroupEntity) group);
for (ServiceGroupFlagEntity groupFlag : groupFlagList) {
groupFlag.setStatus(ServiceGroupStatus.DIRTY);
groupFlagDao.persist(groupFlag);
}
}
}
MultipleGroupEvent mge = new MultipleGroupEvent(allChangedGroups);
try {
eventSubmitter.submit(mge, EventType.GROUP_UPDATE, auditor.getActualExecutor());
} catch (EventSubmitException e) {
logger.warn("Exeption", e);
}
return allChangedGroups;
}
protected Set<GroupEntity> updatePrimary(UserEntity user, Map<String, List<Object>> attributeMap, Auditor auditor)
throws UserUpdateException {
Set<GroupEntity> changedGroups = new HashSet<GroupEntity>();
GroupServiceHook completeOverrideHook = null;
Set<GroupServiceHook> activeHooks = new HashSet<GroupServiceHook>();
HomeOrgGroupEntity group = null;
for (GroupServiceHook hook : hookManager.getGroupHooks()) {
if (hook.isPrimaryResponsible(user, attributeMap)) {
group = hook.preUpdateUserPrimaryGroupFromAttribute(dao, groupDao, group, user, attributeMap, auditor, changedGroups);
activeHooks.add(hook);
if (hook.isPrimaryCompleteOverride()) {
completeOverrideHook = hook;
}
}
}
if (completeOverrideHook == null) {
String homeId = attrHelper.getSingleStringFirst(attributeMap, "http://bwidm.de/bwidmOrgId");
if (homeId == null) {
logger.warn("No Home ID is set for User {}, resetting primary group", user.getEppn());
}
else {
//Filter all non character from homeid
homeId = homeId.toLowerCase();
homeId = homeId.replaceAll("[^a-z]", "");
String groupName = attrHelper.getSingleStringFirst(attributeMap, "http://bwidm.de/bwidmCC");
if (groupName == null) {
groupName = homeId;
}
else {
//Filter all non character from groupName
groupName = Normalizer.normalize(groupName, Normalizer.Form.NFD);
groupName = groupName.toLowerCase();
groupName = groupName.replaceAll("[^a-z0-9\\-_]", "");
}
logger.info("Setting standard HomeID group for user {}", user.getEppn());
group = dao.findByNameAndPrefix(groupName, homeId);
if (group == null) {
group = dao.createNew();
group.setUsers(new HashSet<UserGroupEntity>());
group.setName(groupName);
auditor.logAction(group.getName(), "SET FIELD", "name", group.getName(), AuditStatus.SUCCESS);
group.setPrefix(homeId);
auditor.logAction(group.getName(), "SET FIELD", "prefix", group.getPrefix(), AuditStatus.SUCCESS);
group.setGidNumber(serialService.next("gid-number-serial").intValue());
auditor.logAction(group.getName(), "SET FIELD", "gidNumber", "" + group.getGidNumber(), AuditStatus.SUCCESS);
group.setIdp(user.getIdp());
auditor.logAction(group.getName(), "SET FIELD", "idpEntityId", "" + user.getIdp().getEntityId(), AuditStatus.SUCCESS);
group = dao.persistWithServiceFlags(group);
auditor.logAction(group.getName(), "CREATE GROUP", null, "Group created", AuditStatus.SUCCESS);
changedGroups.add(group);
}
}
}
else {
logger.info("Overriding standard Primary Group Update Mechanism! Activator: {}", completeOverrideHook.getClass().getName());
}
if (group == null) {
logger.warn("No Primary Group for user {}", user.getEppn());
}
for (GroupServiceHook hook : activeHooks) {
group = hook.postUpdateUserPrimaryGroupFromAttribute(dao, groupDao, group, user, attributeMap, auditor, changedGroups);
}
if (user.getPrimaryGroup() != null && (! user.getPrimaryGroup().equals(group))) {
if (group == null) {
auditor.logAction(user.getEppn(), "UPDATE FIELD", "primaryGroup",
user.getPrimaryGroup().getName() + " (" + user.getPrimaryGroup().getGidNumber() + ") -> " +
"null", AuditStatus.SUCCESS);
}
else {
auditor.logAction(user.getEppn(), "UPDATE FIELD", "primaryGroup",
user.getPrimaryGroup().getName() + " (" + user.getPrimaryGroup().getGidNumber() + ") -> " +
group.getName() + " (" + group.getGidNumber() + ")", AuditStatus.SUCCESS);
}
}
else if (user.getPrimaryGroup() == null && group != null) {
auditor.logAction(user.getEppn(), "UPDATE FIELD", "primaryGroup",
"null -> " +
group.getName() + " (" + group.getGidNumber() + ")", AuditStatus.SUCCESS);
}
user.setPrimaryGroup(group);
return changedGroups;
}
protected Set<GroupEntity> updateSecondary(UserEntity user, Map<String, List<Object>> attributeMap, Auditor auditor)
throws UserUpdateException {
Set<GroupEntity> changedGroups = new HashSet<GroupEntity>();
GroupServiceHook completeOverrideHook = null;
Set<GroupServiceHook> activeHooks = new HashSet<GroupServiceHook>();
for (GroupServiceHook hook : hookManager.getGroupHooks()) {
if (hook.isSecondaryResponsible(user, attributeMap)) {
hook.preUpdateUserSecondaryGroupFromAttribute(dao, groupDao, user, attributeMap, auditor, changedGroups);
activeHooks.add(hook);
if (hook.isSecondaryCompleteOverride()) {
completeOverrideHook = hook;
}
}
}
if (completeOverrideHook == null) {
String homeId = attrHelper.getSingleStringFirst(attributeMap, "http://bwidm.de/bwidmOrgId");
List<String> groupList = new ArrayList<String>();
if (homeId == null) {
logger.warn("No Home ID is set for User {}, resetting secondary groups", user.getEppn());
}
else if (attributeMap.get("http://bwidm.de/bwidmMemberOf") == null) {
logger.info("No http://bwidm.de/bwidmMemberOf is set. Resetting secondary groups");
}
else {
List<String> groupsFromAttr = attrHelper.attributeListToStringList(attributeMap, "http://bwidm.de/bwidmMemberOf");
//Check if a group name contains a ';', and divide this group
for (String group : groupsFromAttr) {
if (group.contains(";")) {
String[] splitGroups = group.split(";");
for (String g : splitGroups) {
groupList.add(filterGroup(g));
}
}
else {
groupList.add(filterGroup(group));
}
}
}
if (user.getGroups() == null)
user.setGroups(new HashSet<UserGroupEntity>());
Set<GroupEntity> groupsFromAssertion = new HashSet<GroupEntity>();
logger.debug("Looking up groups from database");
Map<String, HomeOrgGroupEntity> dbGroupMap = new HashMap<String, HomeOrgGroupEntity>();
logger.debug("Indexing groups from database");
for (HomeOrgGroupEntity dbGroup : dao.findByNameListAndPrefix(groupList, homeId)) {
dbGroupMap.put(dbGroup.getName(), dbGroup);
}
for (String group : groupList) {
if (group != null && (!group.equals(""))) {
logger.debug("Analyzing group {}", group);
HomeOrgGroupEntity groupEntity = dbGroupMap.get(group);
try {
if (groupEntity == null) {
int gidNumber = serialService.next("gid-number-serial").intValue();
logger.info("Creating group {} with gidNumber {}", group, gidNumber);
groupEntity = dao.createNew();
groupEntity.setUsers(new HashSet<UserGroupEntity>());
groupEntity.setParents(new HashSet<GroupEntity>());
groupEntity.setName(group);
auditor.logAction(groupEntity.getName(), "SET FIELD", "name", groupEntity.getName(), AuditStatus.SUCCESS);
groupEntity.setPrefix(homeId);
auditor.logAction(groupEntity.getName(), "SET FIELD", "prefix", groupEntity.getPrefix(), AuditStatus.SUCCESS);
groupEntity.setGidNumber(gidNumber);
auditor.logAction(groupEntity.getName(), "SET FIELD", "gidNumber", "" + groupEntity.getGidNumber(), AuditStatus.SUCCESS);
groupEntity.setIdp(user.getIdp());
auditor.logAction(groupEntity.getName(), "SET FIELD", "idpEntityId", "" + user.getIdp().getEntityId(), AuditStatus.SUCCESS);
groupEntity = dao.persistWithServiceFlags(groupEntity);
auditor.logAction(groupEntity.getName(), "CREATE GROUP", null, "Group created", AuditStatus.SUCCESS);
changedGroups.add(groupEntity);
}
if (groupEntity != null) {
groupsFromAssertion.add(groupEntity);
if (! groupDao.isUserInGroup(user, groupEntity)) {
logger.debug("Adding user {} to group {}", user.getEppn(), groupEntity.getName());
groupDao.addUserToGroup(user, groupEntity);
changedGroups.remove(groupEntity);
groupEntity = dao.persist(groupEntity);
auditor.logAction(user.getEppn(), "ADD TO GROUP", groupEntity.getName(), null, AuditStatus.SUCCESS);
changedGroups.add(groupEntity);
}
}
} catch (NumberFormatException e) {
logger.warn("GidNumber has a bad number format: {}", e.getMessage());
}
}
}
Set<GroupEntity> groupsToRemove = new HashSet<GroupEntity>(groupDao.findByUser(user));
groupsToRemove.removeAll(groupsFromAssertion);
for (GroupEntity removeGroup : groupsToRemove) {
if (removeGroup instanceof HomeOrgGroupEntity) {
if (! removeGroup.equals(user.getPrimaryGroup())) {
logger.debug("Removing user {} from group {}", user.getEppn(), removeGroup.getName());
groupDao.removeUserGromGroup(user, removeGroup);
auditor.logAction(user.getEppn(), "REMOVE FROM GROUP", removeGroup.getName(), null, AuditStatus.SUCCESS);
changedGroups.add(removeGroup);
}
}
else {
logger.debug("Group {} of type {}. Doing nothing.", removeGroup.getName(), removeGroup.getClass().getSimpleName());
}
}
/*
* Add Primary group to secondary as well
*/
if (user.getPrimaryGroup() != null && (! groupDao.isUserInGroup(user, user.getPrimaryGroup()))) {
logger.debug("Adding user {} to his primary group {} as secondary", user.getEppn(), user.getPrimaryGroup().getName());
groupDao.addUserToGroup(user, user.getPrimaryGroup());
changedGroups.add(user.getPrimaryGroup());
}
}
else {