Commit 5ee8ae5c authored by ls1947's avatar ls1947
Browse files

Refactor RegisterUserService and ApprovalService

add better support for parent services and speedup things a lot
parent ae2b4a7a
......@@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
......@@ -55,11 +56,13 @@ import edu.kit.scc.webreg.event.EventSubmitter;
import edu.kit.scc.webreg.event.UserEvent;
import edu.kit.scc.webreg.exc.EventSubmitException;
import edu.kit.scc.webreg.exc.MetadataException;
import edu.kit.scc.webreg.exc.RegisterException;
import edu.kit.scc.webreg.exc.UserUpdateException;
import edu.kit.scc.webreg.service.SerialService;
import edu.kit.scc.webreg.service.ServiceService;
import edu.kit.scc.webreg.service.UserServiceHook;
import edu.kit.scc.webreg.service.reg.AttributeSourceQueryService;
import edu.kit.scc.webreg.service.reg.impl.Registrator;
import edu.kit.scc.webreg.service.saml.AttributeQueryHelper;
import edu.kit.scc.webreg.service.saml.Saml2AssertionService;
import edu.kit.scc.webreg.service.saml.SamlHelper;
......@@ -131,6 +134,9 @@ public class UserUpdater implements Serializable {
@Inject
private ApplicationConfig appConfig;
@Inject
private Registrator registrator;
public SamlUserEntity updateUser(SamlUserEntity user, Map<String, List<Object>> attributeMap, String executor)
throws UserUpdateException {
......@@ -152,6 +158,10 @@ public class UserUpdater implements Serializable {
auditor.setName(getClass().getName() + "-UserUpdate-Audit");
auditor.setDetail("Update user " + user.getEppn());
// List to store parent services, that are not registered. Need to be registered
// later, when attribute map is populated
List<ServiceEntity> delayedRegisterList = new ArrayList<ServiceEntity>();
/**
* put no_assertion_count in generic store if assertion is missing. Else
* reset no assertion count and put last valid assertion date in
......@@ -200,6 +210,18 @@ public class UserUpdater implements Serializable {
RegistryStatus.ON_HOLD);
for (RegistryEntity registry : registryList) {
changeRegistryStatus(registry, RegistryStatus.LOST_ACCESS, auditor);
/*
* check if parent registry is missing
*/
if (registry.getService().getParentService() != null) {
List<RegistryEntity> parentRegistryList = registryDao.findByServiceAndUserAndNotStatus(
registry.getService().getParentService(), user,
RegistryStatus.DELETED, RegistryStatus.DEPROVISIONED);
if (parentRegistryList.size() == 0) {
delayedRegisterList.add(registry.getService().getParentService());
}
}
}
/*
......@@ -240,6 +262,15 @@ public class UserUpdater implements Serializable {
attributeStore.put(entry.getKey(), attrHelper.attributeListToString(entry.getValue()));
}
}
for (ServiceEntity delayedService : delayedRegisterList) {
try {
registrator.registerUser(user, delayedService,
"user-" + user.getId(), false);
} catch (RegisterException e) {
logger.warn("Parent registrytion didn't work out like it should", e);
}
}
user.setLastUpdate(new Date());
user.setLastFailedUpdate(null);
......
......@@ -10,242 +10,39 @@
******************************************************************************/
package edu.kit.scc.webreg.service.reg.impl;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import javax.ejb.Stateless;
import javax.inject.Inject;
import org.slf4j.Logger;
import edu.kit.scc.webreg.audit.ApprovalAuditor;
import edu.kit.scc.webreg.audit.Auditor;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.dao.RegistryDao;
import edu.kit.scc.webreg.dao.ServiceDao;
import edu.kit.scc.webreg.dao.ServiceEventDao;
import edu.kit.scc.webreg.dao.ServiceGroupFlagDao;
import edu.kit.scc.webreg.dao.UserDao;
import edu.kit.scc.webreg.dao.audit.AuditDetailDao;
import edu.kit.scc.webreg.dao.audit.AuditEntryDao;
import edu.kit.scc.webreg.entity.EventEntity;
import edu.kit.scc.webreg.entity.EventType;
import edu.kit.scc.webreg.entity.GroupEntity;
import edu.kit.scc.webreg.entity.RegistryEntity;
import edu.kit.scc.webreg.entity.RegistryStatus;
import edu.kit.scc.webreg.entity.ServiceBasedGroupEntity;
import edu.kit.scc.webreg.entity.ServiceEntity;
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.entity.audit.AuditStatus;
import edu.kit.scc.webreg.event.EventSubmitter;
import edu.kit.scc.webreg.event.MultipleGroupEvent;
import edu.kit.scc.webreg.event.ServiceRegisterEvent;
import edu.kit.scc.webreg.exc.EventSubmitException;
import edu.kit.scc.webreg.exc.RegisterException;
import edu.kit.scc.webreg.script.ScriptingEnv;
import edu.kit.scc.webreg.service.reg.ApprovalService;
import edu.kit.scc.webreg.service.reg.ApprovalWorkflow;
import edu.kit.scc.webreg.service.reg.RegisterUserWorkflow;
import edu.kit.scc.webreg.service.reg.ScriptingWorkflow;
@Stateless
public class ApprovalServiceImpl implements ApprovalService {
@Inject
private Logger logger;
@Inject
private ServiceDao serviceDao;
@Inject
private UserDao userDao;
@Inject
private AuditEntryDao auditDao;
@Inject
private AuditDetailDao auditDetailDao;
@Inject
private RegistryDao registryDao;
@Inject
private ServiceGroupFlagDao groupFlagDao;
@Inject
private ServiceEventDao serviceEventDao;
@Inject
private EventSubmitter eventSubmitter;
@Inject
private ApplicationConfig appConfig;
@Inject
private ScriptingEnv scriptingEnv;
private Approvor approvor;
@Override
public void registerApproval(RegistryEntity registry, Auditor parentAuditor) throws RegisterException {
ApprovalWorkflow workflow = getApprovalWorkflowInstance(registry.getApprovalBean());
workflow.startWorkflow(registry);
registry = registryDao.persist(registry);
ServiceRegisterEvent serviceRegisterEvent = new ServiceRegisterEvent(registry);
List<EventEntity> eventList = new ArrayList<EventEntity>(serviceEventDao.findAllByService(registry.getService()));
try {
eventSubmitter.submit(serviceRegisterEvent, eventList, EventType.APPROVAL_START, "user-self");
} catch (EventSubmitException e) {
logger.warn("Exeption", e);
}
approvor.registerApproval(registry, parentAuditor);
}
@Override
public void denyApproval(RegistryEntity registry, String executor, Auditor parentAuditor) throws RegisterException {
ApprovalAuditor auditor = new ApprovalAuditor(auditDao, auditDetailDao, appConfig);
auditor.startAuditTrail(executor, true);
auditor.setName(this.getClass().getName() + "-ApprovalDeny-Audit");
auditor.setDetail("Deny user " + registry.getUser().getEppn() + " for service " + registry.getService().getName());
auditor.setParent(parentAuditor);
auditor.setRegistry(registry);
registry.setRegistryStatus(RegistryStatus.DELETED);
registry = registryDao.persist(registry);
auditor.logAction(registry.getUser().getEppn(), "DENY APPROVAL", "registry-" + registry.getId(), "User is denied acces for service", AuditStatus.SUCCESS);
ServiceRegisterEvent serviceRegisterEvent = new ServiceRegisterEvent(registry, auditor.getAudit());
List<EventEntity> eventList = new ArrayList<EventEntity>(serviceEventDao.findAllByService(registry.getService()));
try {
eventSubmitter.submit(serviceRegisterEvent, eventList, EventType.APPROVAL_DENIED, executor);
} catch (EventSubmitException e) {
logger.warn("Exeption", e);
}
auditor.finishAuditTrail();
if (parentAuditor == null)
auditor.commitAuditTrail();
approvor.denyApproval(registry, executor, parentAuditor);
}
@Override
public void approve(RegistryEntity registry, String executor, Auditor parentAuditor)
throws RegisterException {
approve(registry, executor, true, parentAuditor);
approvor.approve(registry, executor, true, parentAuditor);
}
@Override
public void approve(RegistryEntity registry, String executor, Boolean sendGroupUpdate, Auditor parentAuditor)
throws RegisterException {
logger.info("Finally approving registry {} for user {} and service {}", registry.getId(),
registry.getUser().getEppn(), registry.getService().getName());
RegisterUserWorkflow workflow = getRegisterWorkflowInstance(registry.getRegisterBean());
try {
/**
* TODO findByIdWithAll is slow. Is it really necessary here?
*/
ServiceEntity serviceEntity = serviceDao.findByIdWithServiceProps(registry.getService().getId());
//UserEntity userEntity = userDao.findByIdWithAll(registry.getUser().getId());
UserEntity userEntity = userDao.findById(registry.getUser().getId());
ApprovalAuditor auditor = new ApprovalAuditor(auditDao, auditDetailDao, appConfig);
auditor.startAuditTrail(executor, true);
auditor.setName(workflow.getClass().getName() + "-ApprovalApprove-Audit");
auditor.setDetail("Approve user " + userEntity.getEppn() + " for service " + serviceEntity.getName());
auditor.setParent(parentAuditor);
auditor.setRegistry(registry);
workflow.updateRegistry(userEntity, serviceEntity, registry, auditor);
workflow.registerUser(userEntity, serviceEntity, registry, auditor);
registry.setRegistryStatus(RegistryStatus.ACTIVE);
registry.setLastStatusChange(new Date());
registry.setLastReconcile(new Date());
registry = registryDao.persist(registry);
auditor.logAction(registry.getUser().getEppn(), "APPROVE", "registry-" + registry.getId(), "User is approved for service", AuditStatus.SUCCESS);
HashSet<GroupEntity> userGroups = new HashSet<GroupEntity>(userEntity.getGroups().size());
for (UserGroupEntity userGroup : userEntity.getGroups()) {
GroupEntity group = userGroup.getGroup();
userGroups.add(group);
if (group instanceof ServiceBasedGroupEntity) {
List<ServiceGroupFlagEntity> groupFlagList = groupFlagDao.findByGroupAndService((ServiceBasedGroupEntity) group, serviceEntity);
for (ServiceGroupFlagEntity groupFlag : groupFlagList) {
groupFlag.setStatus(ServiceGroupStatus.DIRTY);
groupFlag = groupFlagDao.persist(groupFlag);
}
}
}
if (sendGroupUpdate) {
MultipleGroupEvent mge = new MultipleGroupEvent(userGroups);
try {
eventSubmitter.submit(mge, EventType.GROUP_UPDATE, auditor.getActualExecutor());
} catch (EventSubmitException e) {
logger.warn("Exeption", e);
}
}
ServiceRegisterEvent serviceRegisterEvent = new ServiceRegisterEvent(registry, auditor.getAudit());
List<EventEntity> eventList = new ArrayList<EventEntity>(serviceEventDao.findAllByService(serviceEntity));
eventSubmitter.submit(serviceRegisterEvent, eventList, EventType.SERVICE_REGISTER, executor);
auditor.finishAuditTrail();
if (parentAuditor == null)
auditor.commitAuditTrail();
} catch (Throwable t) {
throw new RegisterException(t);
}
approvor.approve(registry, executor, sendGroupUpdate, parentAuditor);
}
private RegisterUserWorkflow getRegisterWorkflowInstance(String className) {
try {
Object o = Class.forName(className).getConstructor().newInstance();
if (o instanceof RegisterUserWorkflow) {
if (o instanceof ScriptingWorkflow)
((ScriptingWorkflow) o).setScriptingEnv(scriptingEnv);
return (RegisterUserWorkflow) o;
}
else {
logger.warn("Service Register bean misconfigured, Object not Type RegisterUserWorkflow but: {}", o.getClass());
return null;
}
} catch (InstantiationException | NoSuchMethodException | IllegalAccessException |
ClassNotFoundException | InvocationTargetException e) {
logger.warn("Service Register bean misconfigured: {}", e.getMessage());
return null;
}
}
private ApprovalWorkflow getApprovalWorkflowInstance(String className) {
try {
Object o = Class.forName(className).getConstructor().newInstance();
if (o instanceof ApprovalWorkflow)
return (ApprovalWorkflow) o;
else {
logger.warn("Service Register bean misconfigured, Object not Type ApprovalWorkflow but: {}", o.getClass());
return null;
}
} catch (InstantiationException | NoSuchMethodException | IllegalAccessException |
ClassNotFoundException | InvocationTargetException e) {
logger.warn("Service Register bean misconfigured: {}", e.getMessage());
return null;
}
}
}
/*******************************************************************************
* 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.reg.impl;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.slf4j.Logger;
import edu.kit.scc.webreg.audit.ApprovalAuditor;
import edu.kit.scc.webreg.audit.Auditor;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.dao.RegistryDao;
import edu.kit.scc.webreg.dao.ServiceEventDao;
import edu.kit.scc.webreg.dao.ServiceGroupFlagDao;
import edu.kit.scc.webreg.dao.audit.AuditDetailDao;
import edu.kit.scc.webreg.dao.audit.AuditEntryDao;
import edu.kit.scc.webreg.entity.EventEntity;
import edu.kit.scc.webreg.entity.EventType;
import edu.kit.scc.webreg.entity.GroupEntity;
import edu.kit.scc.webreg.entity.RegistryEntity;
import edu.kit.scc.webreg.entity.RegistryStatus;
import edu.kit.scc.webreg.entity.ServiceBasedGroupEntity;
import edu.kit.scc.webreg.entity.ServiceEntity;
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.entity.audit.AuditStatus;
import edu.kit.scc.webreg.event.EventSubmitter;
import edu.kit.scc.webreg.event.MultipleGroupEvent;
import edu.kit.scc.webreg.event.ServiceRegisterEvent;
import edu.kit.scc.webreg.exc.EventSubmitException;
import edu.kit.scc.webreg.exc.RegisterException;
import edu.kit.scc.webreg.script.ScriptingEnv;
import edu.kit.scc.webreg.service.reg.ApprovalWorkflow;
import edu.kit.scc.webreg.service.reg.RegisterUserWorkflow;
import edu.kit.scc.webreg.service.reg.ScriptingWorkflow;
@ApplicationScoped
public class Approvor implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private Logger logger;
@Inject
private AuditEntryDao auditDao;
@Inject
private AuditDetailDao auditDetailDao;
@Inject
private RegistryDao registryDao;
@Inject
private ServiceGroupFlagDao groupFlagDao;
@Inject
private ServiceEventDao serviceEventDao;
@Inject
private EventSubmitter eventSubmitter;
@Inject
private ApplicationConfig appConfig;
@Inject
private ScriptingEnv scriptingEnv;
public void registerApproval(RegistryEntity registry, Auditor parentAuditor) throws RegisterException {
registry = registryDao.merge(registry);
ApprovalWorkflow workflow = getApprovalWorkflowInstance(registry.getApprovalBean());
workflow.startWorkflow(registry);
ServiceRegisterEvent serviceRegisterEvent = new ServiceRegisterEvent(registry);
List<EventEntity> eventList = new ArrayList<EventEntity>(serviceEventDao.findAllByService(registry.getService()));
try {
eventSubmitter.submit(serviceRegisterEvent, eventList, EventType.APPROVAL_START, "user-self");
} catch (EventSubmitException e) {
logger.warn("Exeption", e);
}
}
public void denyApproval(RegistryEntity registry, String executor, Auditor parentAuditor) throws RegisterException {
registry = registryDao.merge(registry);
ApprovalAuditor auditor = new ApprovalAuditor(auditDao, auditDetailDao, appConfig);
auditor.startAuditTrail(executor, true);
auditor.setName(this.getClass().getName() + "-ApprovalDeny-Audit");
auditor.setDetail("Deny user " + registry.getUser().getEppn() + " for service " + registry.getService().getName());
auditor.setParent(parentAuditor);
auditor.setRegistry(registry);
registry.setRegistryStatus(RegistryStatus.DELETED);
auditor.logAction(registry.getUser().getEppn(), "DENY APPROVAL", "registry-" + registry.getId(), "User is denied acces for service", AuditStatus.SUCCESS);
ServiceRegisterEvent serviceRegisterEvent = new ServiceRegisterEvent(registry, auditor.getAudit());
List<EventEntity> eventList = new ArrayList<EventEntity>(serviceEventDao.findAllByService(registry.getService()));
try {
eventSubmitter.submit(serviceRegisterEvent, eventList, EventType.APPROVAL_DENIED, executor);
} catch (EventSubmitException e) {
logger.warn("Exeption", e);
}
auditor.finishAuditTrail();
if (parentAuditor == null)
auditor.commitAuditTrail();
}
public void approve(RegistryEntity registry, String executor, Auditor parentAuditor)
throws RegisterException {
approve(registry, executor, true, parentAuditor);
}
public void approve(RegistryEntity registry, String executor, Boolean sendGroupUpdate, Auditor parentAuditor)
throws RegisterException {
logger.info("Finally approving registry {} for user {} and service {}", registry.getId(),
registry.getUser().getEppn(), registry.getService().getName());
registry = registryDao.merge(registry);
RegisterUserWorkflow workflow = getRegisterWorkflowInstance(registry.getRegisterBean());
try {
ServiceEntity serviceEntity = registry.getService();
UserEntity userEntity = registry.getUser();
ApprovalAuditor auditor = new ApprovalAuditor(auditDao, auditDetailDao, appConfig);
auditor.startAuditTrail(executor, true);
auditor.setName(workflow.getClass().getName() + "-ApprovalApprove-Audit");
auditor.setDetail("Approve user " + userEntity.getEppn() + " for service " + serviceEntity.getName());
auditor.setParent(parentAuditor);
auditor.setRegistry(registry);
workflow.updateRegistry(userEntity, serviceEntity, registry, auditor);
workflow.registerUser(userEntity, serviceEntity, registry, auditor);
registry.setRegistryStatus(RegistryStatus.ACTIVE);
registry.setLastStatusChange(new Date());
registry.setLastReconcile(new Date());
auditor.logAction(registry.getUser().getEppn(), "APPROVE", "registry-" + registry.getId(), "User is approved for service", AuditStatus.SUCCESS);
HashSet<GroupEntity> userGroups = new HashSet<GroupEntity>(userEntity.getGroups().size());
for (UserGroupEntity userGroup : userEntity.getGroups()) {
GroupEntity group = userGroup.getGroup();
userGroups.add(group);
if (group instanceof ServiceBasedGroupEntity) {
List<ServiceGroupFlagEntity> groupFlagList = groupFlagDao.findByGroupAndService((ServiceBasedGroupEntity) group, serviceEntity);
for (ServiceGroupFlagEntity groupFlag : groupFlagList) {
groupFlag.setStatus(ServiceGroupStatus.DIRTY);
groupFlag = groupFlagDao.persist(groupFlag);
}
}
}
if (sendGroupUpdate) {
MultipleGroupEvent mge = new MultipleGroupEvent(userGroups);
try {
eventSubmitter.submit(mge, EventType.GROUP_UPDATE, auditor.getActualExecutor());
} catch (EventSubmitException e) {
logger.warn("Exeption", e);
}
}
ServiceRegisterEvent serviceRegisterEvent = new ServiceRegisterEvent(registry, auditor.getAudit());
List<EventEntity> eventList = new ArrayList<EventEntity>(serviceEventDao.findAllByService(serviceEntity));
eventSubmitter.submit(serviceRegisterEvent, eventList, EventType.SERVICE_REGISTER, executor);
auditor.finishAuditTrail();
if (parentAuditor == null)
auditor.commitAuditTrail();
} catch (Throwable t) {
throw new RegisterException(t);
}
}
private RegisterUserWorkflow getRegisterWorkflowInstance(String className) {
try {
Object o = Class.forName(className).getConstructor().newInstance();
if (o instanceof RegisterUserWorkflow) {
if (o instanceof ScriptingWorkflow)
((ScriptingWorkflow) o).setScriptingEnv(scriptingEnv);
return (RegisterUserWorkflow) o;
}
else {
logger.warn("Service Register bean misconfigured, Object not Type RegisterUserWorkflow but: {}", o.getClass());
return null;
}
} catch (InstantiationException | NoSuchMethodException | IllegalAccessException |
ClassNotFoundException | InvocationTargetException e) {
logger.warn("Service Register bean misconfigured: {}", e.getMessage());
return null;
}
}
private ApprovalWorkflow getApprovalWorkflowInstance(String className) {
try {
Object o = Class.forName(className).getConstructor().newInstance();
if (o instanceof ApprovalWorkflow)
return (ApprovalWorkflow) o;
else {
logger.warn("Service Register bean misconfigured, Object not Type ApprovalWorkflow but: {}", o.getClass());
return null;
}
} catch (InstantiationException | NoSuchMethodException | IllegalAccessException |
ClassNotFoundException | InvocationTargetException e) {
logger.warn("Service Register bean misconfigured: {}", e.getMessage());
return null;
}
}
}