Commit 239a9213 authored by michael.simon's avatar michael.simon
Browse files

add delete all my personal data functionality

parent 8653a083
/*******************************************************************************
* 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.entity.audit;
import javax.persistence.Entity;
@Entity(name = "AuditUserDeleteEntity")
public class AuditUserDeleteEntity extends AuditUserEntity {
private static final long serialVersionUID = 1L;
}
package edu.kit.scc.webreg.entity.audit;
import javax.annotation.Generated;
import javax.persistence.metamodel.StaticMetamodel;
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(AuditUserDeleteEntity.class)
public abstract class AuditUserDeleteEntity_ extends edu.kit.scc.webreg.entity.audit.AuditUserEntity_ {
}
/*******************************************************************************
* 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.audit;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.dao.audit.AuditDetailDao;
import edu.kit.scc.webreg.dao.audit.AuditEntryDao;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.entity.audit.AuditUserDeleteEntity;
public class UserDeleteAuditor extends AbstractAuditor<AuditUserDeleteEntity> {
private static final long serialVersionUID = 1L;
public UserDeleteAuditor(AuditEntryDao auditEntryDao,
AuditDetailDao auditDetailDao, ApplicationConfig appConfig) {
super(auditEntryDao, auditDetailDao, appConfig);
}
public void setUser(UserEntity entity) {
audit.setUser(entity);
}
@Override
protected AuditUserDeleteEntity newInstance() {
return new AuditUserDeleteEntity();
}
}
package edu.kit.scc.webreg.service;
import edu.kit.scc.webreg.entity.SamlUserEntity;
public interface UserDeleteService {
void deleteUserData(SamlUserEntity user, String executor);
}
/*******************************************************************************
* 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.impl;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.inject.Inject;
import org.slf4j.Logger;
import edu.kit.scc.webreg.audit.UserDeleteAuditor;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.dao.GroupDao;
import edu.kit.scc.webreg.dao.RegistryDao;
import edu.kit.scc.webreg.dao.RoleDao;
import edu.kit.scc.webreg.dao.SamlUserDao;
import edu.kit.scc.webreg.dao.audit.AuditDetailDao;
import edu.kit.scc.webreg.dao.audit.AuditEntryDao;
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.RoleEntity;
import edu.kit.scc.webreg.entity.SamlUserEntity;
import edu.kit.scc.webreg.entity.UserStatus;
import edu.kit.scc.webreg.exc.RegisterException;
import edu.kit.scc.webreg.service.UserDeleteService;
import edu.kit.scc.webreg.service.reg.ApprovalService;
import edu.kit.scc.webreg.service.reg.RegisterUserService;
@Stateless
public class UserDeleteServiceImpl implements UserDeleteService {
@Inject
private Logger logger;
@Inject
private RegisterUserService registerUserService;
@Inject
private ApprovalService approvalService;
@Inject
private AuditEntryDao auditEntryDao;
@Inject
private AuditDetailDao auditDetailDao;
@Inject
private SamlUserDao samlUserDao;
@Inject
private RegistryDao registryDao;
@Inject
private GroupDao groupDao;
@Inject
private RoleDao roleDao;
@Inject
private ApplicationConfig appConfig;
@Override
public void deleteUserData(SamlUserEntity user, String executor) {
logger.info("Delete all personal user data for user {}, {}", user.getEppn(), user.getId());
user = samlUserDao.findById(user.getId());
UserDeleteAuditor auditor = new UserDeleteAuditor(auditEntryDao, auditDetailDao, appConfig);
auditor.startAuditTrail(executor, true);
List<RegistryEntity> registryList = registryDao.findByUser(user);
for (RegistryEntity registry : registryList) {
logger.info("Delete all personal user data: Check registry {} for deregister", registry.getId());
/*
* Deregister Services with ACTIVE, LOST_ACCESS or ON_HOLD first
*/
if ((RegistryStatus.ACTIVE == registry.getRegistryStatus()) ||
(RegistryStatus.LOST_ACCESS == registry.getRegistryStatus()) ||
(RegistryStatus.ON_HOLD == registry.getRegistryStatus())) {
try {
registerUserService.deregisterUser(registry, executor, auditor);
} catch (RegisterException e) {
logger.warn("Exception while deregister user", e);
}
}
if (RegistryStatus.PENDING == registry.getRegistryStatus()) {
try {
approvalService.denyApproval(registry, executor, auditor);
} catch (RegisterException e) {
logger.warn("Exception while deny approval", e);
}
}
}
for (RegistryEntity registry : registryList) {
logger.info("Delete all personal user data: Scrubbing registry {}", registry.getId());
registry.getRegistryValues().clear();
}
List<GroupEntity> groupList = groupDao.findByUser(user);
for (GroupEntity group : groupList) {
logger.info("Delete all personal user data: Remove user {} grom group {}", user.getId(), group.getId());
groupDao.removeUserGromGroup(user, group);
}
user.getGenericStore().clear();
user.getAttributeStore().clear();
user.getUserAttrs().clear();
user.getEmailAddresses().clear();
user.setEmail(null);
user.setEppn(null);
user.setGivenName(null);
user.setSurName(null);
user.setPersistentId(null);
user.setUserStatus(UserStatus.DEREGISTERED);
user.setLastStatusChange(new Date());
List<RoleEntity> roleList = roleDao.findByUser(user);
for (RoleEntity role : roleList) {
logger.info("Delete all personal user data: Remove user {} grom role {}", user.getId(), role.getName());
roleDao.deleteUserRole(user.getId(), role.getName());
}
auditor.finishAuditTrail();
auditor.commitAuditTrail();
}
}
...@@ -31,6 +31,9 @@ public interface RegisterUserService { ...@@ -31,6 +31,9 @@ public interface RegisterUserService {
void reconsiliation(RegistryEntity registry, Boolean fullRecon, void reconsiliation(RegistryEntity registry, Boolean fullRecon,
String executor, Auditor parentAuditor) throws RegisterException; String executor, Auditor parentAuditor) throws RegisterException;
void deregisterUser(RegistryEntity registry, String executor, Auditor parentAuditor)
throws RegisterException;
void deregisterUser(RegistryEntity registry, String executor) void deregisterUser(RegistryEntity registry, String executor)
throws RegisterException; throws RegisterException;
......
...@@ -471,6 +471,11 @@ public class RegisterUserServiceImpl implements RegisterUserService { ...@@ -471,6 +471,11 @@ public class RegisterUserServiceImpl implements RegisterUserService {
@Override @Override
public void deregisterUser(RegistryEntity registry, String executor) throws RegisterException { public void deregisterUser(RegistryEntity registry, String executor) throws RegisterException {
deregisterUser(registry, executor, null);
}
@Override
public void deregisterUser(RegistryEntity registry, String executor, Auditor parentAuditor) throws RegisterException {
if (RegistryStatus.DELETED.equals(registry.getRegistryStatus())) { if (RegistryStatus.DELETED.equals(registry.getRegistryStatus())) {
throw new RegisterException("Registry " + registry.getId() + " is already deregistered!"); throw new RegisterException("Registry " + registry.getId() + " is already deregistered!");
...@@ -486,6 +491,7 @@ public class RegisterUserServiceImpl implements RegisterUserService { ...@@ -486,6 +491,7 @@ public class RegisterUserServiceImpl implements RegisterUserService {
auditor.startAuditTrail(executor); auditor.startAuditTrail(executor);
auditor.setName(workflow.getClass().getName() + "-Deregister-Audit"); auditor.setName(workflow.getClass().getName() + "-Deregister-Audit");
auditor.setDetail("Deregister user " + registry.getUser().getEppn() + " for service " + serviceEntity.getName()); auditor.setDetail("Deregister user " + registry.getUser().getEppn() + " for service " + serviceEntity.getName());
auditor.setParent(parentAuditor);
auditor.setRegistry(registry); auditor.setRegistry(registry);
workflow.deregisterUser(userEntity, serviceEntity, registry, auditor); workflow.deregisterUser(userEntity, serviceEntity, registry, auditor);
...@@ -523,7 +529,9 @@ public class RegisterUserServiceImpl implements RegisterUserService { ...@@ -523,7 +529,9 @@ public class RegisterUserServiceImpl implements RegisterUserService {
eventSubmitter.submit(serviceRegisterEvent, eventList, EventType.SERVICE_DEREGISTER, executor); eventSubmitter.submit(serviceRegisterEvent, eventList, EventType.SERVICE_DEREGISTER, executor);
auditor.finishAuditTrail(); auditor.finishAuditTrail();
auditor.commitAuditTrail(); if (parentAuditor == null) {
auditor.commitAuditTrail();
}
} catch (RegisterException e) { } catch (RegisterException e) {
throw e; throw e;
......
/*******************************************************************************
* 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.bean;
import java.io.Serializable;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ComponentSystemEvent;
import javax.inject.Inject;
import edu.kit.scc.webreg.entity.RegistryEntity;
import edu.kit.scc.webreg.entity.SamlUserEntity;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.service.RegistryService;
import edu.kit.scc.webreg.service.UserDeleteService;
import edu.kit.scc.webreg.service.UserService;
import edu.kit.scc.webreg.session.SessionManager;
import edu.kit.scc.webreg.util.ViewIds;
@ManagedBean
@ViewScoped
public class DeleteAllPersonalDataBean implements Serializable {
private static final long serialVersionUID = 1L;
private SamlUserEntity user;
private List<RegistryEntity> registryList;
@Inject
private UserService userService;
@Inject
private UserDeleteService userDeleteService;
@Inject
private RegistryService registryService;
@Inject
private SessionManager sessionManager;
public void preRenderView(ComponentSystemEvent ev) {
if (user == null) {
UserEntity tempUser = userService.findByIdWithStore(sessionManager.getUserId());
if (tempUser instanceof SamlUserEntity) {
user = (SamlUserEntity) tempUser;
}
else {
throw new IllegalArgumentException("This page is only for SAML Users");
}
registryList = registryService.findByUser(user);
}
}
public String cancel() {
return ViewIds.INDEX_USER;
}
public String commit() {
userDeleteService.deleteUserData(user, "user-" + user.getId());
return ViewIds.DELETE_ALL_PERSONAL_DATA_DONE;
}
public UserEntity getUser() {
return user;
}
public List<RegistryEntity> getRegistryList() {
return registryList;
}
}
...@@ -142,8 +142,10 @@ public class ViewIds { ...@@ -142,8 +142,10 @@ public class ViewIds {
public static final String SERVICE_SET_PASSWORD = "/service/set-password.xhtml"; public static final String SERVICE_SET_PASSWORD = "/service/set-password.xhtml";
public static final String INDEX_USER = "/index.xhtml"; public static final String INDEX_USER = "/index.xhtml";
public static final String USER_PROPERTIES = "/user/index.xhtml"; public static final String USER_PROPERTIES = "/user/index.xhtml";
public static final String DELETE_ALL_PERSONAL_DATA = "/user/delete-all-personal-data.xhtml";
public static final String REGISTER_USER = "/register.xhtml"; public static final String REGISTER_USER = "/register.xhtml";
public static final String DISCOVERY_LOGIN = "/welcome/index.xhtml"; public static final String DISCOVERY_LOGIN = "/welcome/index.xhtml";
public static final String DELETE_ALL_PERSONAL_DATA_DONE = "/welcome/delete-all-personal-data-done.xhtml";
public static final String APPROVE_USER = "/service-approver/approve-user.xhtml"; public static final String APPROVE_USER = "/service-approver/approve-user.xhtml";
} }
...@@ -214,6 +214,11 @@ my_data_explanation=Hier k\u00F6nnen Sie alle Daten einsehen, die \u00FCber Sie ...@@ -214,6 +214,11 @@ my_data_explanation=Hier k\u00F6nnen Sie alle Daten einsehen, die \u00FCber Sie
my_data_from_saml=Diese Daten wurde aus folgender SAML Datenlieferung von Ihrem Shibboleth Identity Provider erzeugt. Die letzt Aktualisierung erfolgte am my_data_from_saml=Diese Daten wurde aus folgender SAML Datenlieferung von Ihrem Shibboleth Identity Provider erzeugt. Die letzt Aktualisierung erfolgte am
my_data_groups=Mitgliedschaften in den folgenden Gruppen wurde aus den vorhandenen Daten berechnet: my_data_groups=Mitgliedschaften in den folgenden Gruppen wurde aus den vorhandenen Daten berechnet:
my_data=Meine Daten my_data=Meine Daten
my_data_delete_all=Klicken Sie hier, um alle pers\u00F6nlichen Daten l\u00F6schen zu lassen. Der Link \u00F6ffnet eine neue Seite mit einer Erkl\u00E4rung, was genau gel\u00F6scht wird.
my_data_delete_all_link=Alle Meine Daten l\u00F6schen
my_data_delete_all_header=Meine Daten l\u00F6schen
my_data_delete_all_text=Meine Daten l\u00F6schen
my_data_delete_all_commit=Meine Daten jetzt l\u00F6schen
nameid_format=NameID Format nameid_format=NameID Format
name=Name name=Name
new_approvals=Neue Approvals new_approvals=Neue Approvals
......
...@@ -233,6 +233,11 @@ my_data_explanation=You can see all personal data which is stored. If this data ...@@ -233,6 +233,11 @@ my_data_explanation=You can see all personal data which is stored. If this data
my_data_from_saml=This data is derived from a SAML Assertion from your Shibboleth Identity Provider. Last update was my_data_from_saml=This data is derived from a SAML Assertion from your Shibboleth Identity Provider. Last update was
my_data_groups=The following group memberships are calculated for your account: my_data_groups=The following group memberships are calculated for your account:
my_data=Personal Data my_data=Personal Data
my_data_delete_all=Use this link, in order to get all your personal data deleted. This link opens a new page, with an explanation, what will be deleted.
my_data_delete_all_link=Delete all my personal data
my_data_delete_all_header=Delete my personal data
my_data_delete_all_text=Delete my personal data
my_data_delete_all_commit=Delete my personal data now
nameid_format=NameID Format nameid_format=NameID Format
name=Name name=Name
nameid_format=NameID format nameid_format=NameID format
......
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:bw="http://www.scc.kit.edu/bwfacelets"
xmlns:p="http://primefaces.org/ui"
xmlns:of="http://omnifaces.org/functions">
<head>
<title></title>
</head>
<body>
<f:view>
<f:metadata>
<f:event type="javax.faces.event.PreRenderViewEvent"
listener="#{deleteAllPersonalDataBean.preRenderView}" />
</f:metadata>
<ui:composition template="/template/default.xhtml">
<ui:param name="title" value="#{messages.title}"/>
<ui:define name="content">
<h:form>
<div class="panel">
<h2 style="color: red;"><h:outputText value="#{messages.my_data_delete_all_header}"/></h2>
<p:panel id="blockPanel">
<div class="panel">
<h:outputText value="#{messages.my_data_delete_all_text}"/>
</div>
<div style="margin-top: 16px;">
<p:commandButton id="cancel" action="#{deleteAllPersonalDataBean.cancel}"
value="#{messages.cancel}"/>
<p:commandButton id="save" action="#{deleteAllPersonalDataBean.commit}"
value="#{messages.my_data_delete_all_commit}" style="color: red;"/>
</div>
</p:panel>
<p:blockUI block="blockPanel" trigger="save">
<p:graphicImage value="#{resource['/img/ajax-loader.gif']}" alt="#{messages.loading}" />
</p:blockUI>
</div>
</h:form>
</ui:define>
</ui:composition>
</f:view>
</body>
</html>
...@@ -42,6 +42,12 @@ ...@@ -42,6 +42,12 @@
rendered="#{not empty userPropertiesBean.idpEntity.displayName}"/> rendered="#{not empty userPropertiesBean.idpEntity.displayName}"/>
</p:panelGrid> </p:panelGrid>
<div class="panel">#{messages.my_data_delete_all}
</div>
<div class="panel">
<h:link outcome="/user/delete-all-personal-data.xhtml" value="#{messages.my_data_delete_all_link}">
</h:link>
</div>
</p:tab> </p:tab>
<p:tab id="tab2" title="#{messages.shibboleth}"> <p:tab id="tab2" title="#{messages.shibboleth}">
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment