diff --git a/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java b/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java index f2c5a8dfff039311fd1f57254cddbced4f1598e2..f8dac00140abd7a6c96544d4c1b12c432e9a0150 100644 --- a/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java +++ b/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java @@ -349,8 +349,8 @@ public class BinderDAO { sb.append("select binder from pfbinder as binder") .append(" inner join fetch binder.baseGroup as baseGroup") .append(" inner join baseGroup.members as membership") - .append(" where membership.identity.key=:identityKey and membership.role=:role") - .append(" and (binder.status is null or binder.status='").append(BinderStatus.open.name()).append("')"); + .append(" left join fetch binder.olatResource as resource") + .append(" where membership.identity.key=:identityKey and membership.role=:role"); return dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), Binder.class) diff --git a/src/main/java/org/olat/modules/portfolio/manager/MediaDAO.java b/src/main/java/org/olat/modules/portfolio/manager/MediaDAO.java index d8f086f3e0703d3a01c409ce2f46a009e3d3b348..76be41eaa5d13d2d7a6bfa0db3c1bda275ccca2d 100644 --- a/src/main/java/org/olat/modules/portfolio/manager/MediaDAO.java +++ b/src/main/java/org/olat/modules/portfolio/manager/MediaDAO.java @@ -142,6 +142,14 @@ public class MediaDAO { return query.getResultList(); } + public List<Media> load(IdentityRef author) { + String query = "select media from pfmedia as media where media.author.key=:authorKey"; + return dbInstance.getCurrentEntityManager() + .createQuery(query, Media.class) + .setParameter("authorKey", author.getKey()) + .getResultList(); + } + public List<BinderPageUsage> usedInBinders(MediaLight media) { StringBuilder sb = new StringBuilder(); sb.append("select binder.key, binder.title, page.key, page.title, page.status") @@ -166,7 +174,23 @@ public class MediaDAO { usage.add(new BinderPageUsage(binderKey, binderTitle, pageKey, pageTitle, pageStatus)); } return usage; + } + + public boolean isUsed(MediaLight media) { + StringBuilder sb = new StringBuilder(); + sb.append("select page.key") + .append(" from pfpage as page") + .append(" inner join page.body as pageBody") + .append(" inner join pageBody.parts as bodyPart") + .append(" where bodyPart.media.key=:mediaKey"); + List<Long> pageKey = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Long.class) + .setParameter("mediaKey", media.getKey()) + .setFirstResult(0) + .setMaxResults(1) + .getResultList(); + return pageKey != null && !pageKey.isEmpty() && pageKey.get(0) != null; } public void deleteMedia(Media media) { diff --git a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java index ded1bd8c82a3a1812fa48b6d602e8b56227a6242..27362495ef6ecf8b6ce9b420f0dda513b9e805f7 100644 --- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java +++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java @@ -122,6 +122,7 @@ import org.olat.repository.RepositoryEntryRef; import org.olat.repository.RepositoryService; import org.olat.resource.OLATResource; import org.olat.resource.OLATResourceManager; +import org.olat.user.UserDataDeletable; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -135,7 +136,7 @@ import com.thoughtworks.xstream.XStream; * */ @Service -public class PortfolioServiceImpl implements PortfolioService, DeletableGroupData { +public class PortfolioServiceImpl implements PortfolioService, DeletableGroupData, UserDataDeletable { private static final OLog log = Tracing.createLoggerFor(PortfolioServiceImpl.class); @@ -285,6 +286,37 @@ public class PortfolioServiceImpl implements PortfolioService, DeletableGroupDat return false; } + @Override + public void deleteUserData(Identity identity, String newDeletedUserName, File archivePath) { + List<Binder> ownedBinders = binderDao.getOwnedBinders(identity); + for(Binder ownedBinder:ownedBinders) { + OLATResource resource = ((BinderImpl)ownedBinder).getOlatResource(); + if(resource != null) { + continue;// this is a template + } + + List<Identity> owners = binderDao.getMembers(ownedBinder, PortfolioRoles.owner.name()); + if(owners.size() == 1 && owners.get(0).getKey().equals(identity.getKey())) { + try { + deleteBinder(ownedBinder); + dbInstance.commit(); + } catch (Exception e) { + log.error("Cannot delete binder: " + ownedBinder.getKey()); + dbInstance.rollbackAndCloseSession(); + } + } + } + + List<Media> medias = mediaDao.load(identity); + for(Media media:medias) { + if(mediaDao.isUsed(media)) { + log.audit("Cannot delete media because used: " + media.getKey()); + } else { + deleteMedia(media); + } + } + } + @Override public boolean detachCourseFromBinders(RepositoryEntry entry) { int deletedRows = binderDao.detachBinderFromRepositoryEntry(entry); diff --git a/src/main/java/org/olat/modules/portfolio/ui/MediaCenterController.java b/src/main/java/org/olat/modules/portfolio/ui/MediaCenterController.java index 010a2364a01f6605f1ecaf3d92efb27e01e731f0..b6cb37974be361d3857fdb663acddacd67370030 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/MediaCenterController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/MediaCenterController.java @@ -255,7 +255,7 @@ public class MediaCenterController extends FormBasicController String searchString = tableEl.getQuickSearchString(); List<String> tagNames = getSelectedTagNames(); Map<Long,MediaRow> currentMap = model.getObjects() - .stream().collect(Collectors.toMap(r -> r.getKey(), r -> r)); + .stream().collect(Collectors.toMap(MediaRow::getKey, r -> r)); List<MediaLight> medias = portfolioService.searchOwnedMedias(getIdentity(), searchString, tagNames); List<MediaRow> rows = new ArrayList<>(medias.size()); diff --git a/src/test/java/org/olat/modules/portfolio/manager/PortfolioServiceTest.java b/src/test/java/org/olat/modules/portfolio/manager/PortfolioServiceTest.java index 0c5e143403bd0b9428e6fd6edf8f477d239a5782..e4f1dc76a5c645610a95a941c1bfd04dd624faab 100644 --- a/src/test/java/org/olat/modules/portfolio/manager/PortfolioServiceTest.java +++ b/src/test/java/org/olat/modules/portfolio/manager/PortfolioServiceTest.java @@ -26,6 +26,7 @@ import java.util.Locale; import org.junit.Assert; import org.junit.Test; +import org.olat.admin.user.delete.service.UserDeletionManager; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.commentAndRating.manager.UserCommentsDAO; import org.olat.core.id.Identity; @@ -34,13 +35,17 @@ import org.olat.core.util.resource.OresHelper; import org.olat.modules.portfolio.Assignment; import org.olat.modules.portfolio.AssignmentType; import org.olat.modules.portfolio.Binder; +import org.olat.modules.portfolio.Media; import org.olat.modules.portfolio.Page; +import org.olat.modules.portfolio.PageBody; import org.olat.modules.portfolio.PortfolioRoles; import org.olat.modules.portfolio.PortfolioService; import org.olat.modules.portfolio.Section; import org.olat.modules.portfolio.SectionRef; +import org.olat.modules.portfolio.handler.TextHandler; import org.olat.modules.portfolio.model.AccessRights; import org.olat.modules.portfolio.model.BinderStatistics; +import org.olat.modules.portfolio.model.MediaPart; import org.olat.modules.portfolio.model.PageImpl; import org.olat.modules.portfolio.model.SectionImpl; import org.olat.modules.portfolio.model.SynchedBinder; @@ -65,6 +70,8 @@ public class PortfolioServiceTest extends OlatTestCase { @Autowired private PageDAO pageDao; @Autowired + private MediaDAO mediaDao; + @Autowired private BinderDAO binderDao; @Autowired private AssignmentDAO assignmentDao; @@ -74,6 +81,8 @@ public class PortfolioServiceTest extends OlatTestCase { private PortfolioService portfolioService; @Autowired private RepositoryService repositoryService; + @Autowired + private UserDeletionManager userDeletionManager; @Test public void createNewOwnedPorfolio() { @@ -1131,5 +1140,67 @@ public class PortfolioServiceTest extends OlatTestCase { Assert.assertTrue(deletedPages.isEmpty()); } - + /** + * Check if the delete user method do its job. + * + */ + @Test + public void deleteUser() { + Identity owner = JunitTestHelper.createAndPersistIdentityAsRndUser("port-u-21"); + RepositoryEntry templateEntry = createTemplate(owner, "Template", "TE"); + dbInstance.commitAndCloseSession(); + + // the user make a template + Binder templateBinder = portfolioService.getBinderByResource(templateEntry.getOlatResource()); + SectionRef templateSectionRef = portfolioService.appendNewSection("1. section ", "Section 1", null, null, templateBinder); + dbInstance.commit(); + Section templateSection = portfolioService.getSection(templateSectionRef); + Assignment assignment = portfolioService.addAssignment("1 Assignment", "", "", AssignmentType.essay, templateSection, false, false, false, null); + Assert.assertNotNull(assignment); + dbInstance.commit(); + + // the user use the template + Binder binder = portfolioService.assignBinder(owner, templateBinder, templateEntry, null, null); + SynchedBinder synchedBinder = portfolioService.loadAndSyncBinder(binder); + binder = synchedBinder.getBinder(); + dbInstance.commitAndCloseSession(); + + // add a media to a page + Section reloadedSection = portfolioService.getSections(binder).get(0); + Page page = pageDao.createAndPersist("Page 1", "A page with content.", null, null, true, reloadedSection, null); + Media media = mediaDao.createMedia("To delete", "Binder", "A media to delete promptly", TextHandler.TEXT_MEDIA, "[Media:0]", null, 10, owner); + dbInstance.commitAndCloseSession(); + MediaPart mediaPart = new MediaPart(); + mediaPart.setMedia(media); + PageBody reloadedBody = pageDao.loadPageBodyByKey(page.getBody().getKey()); + pageDao.persistPart(reloadedBody, mediaPart); + dbInstance.commitAndCloseSession(); + + // add some markers + Identity permanentUser = JunitTestHelper.createAndPersistIdentityAsRndUser("port-u-22"); + Media permanentMedia = mediaDao.createMedia("Permanent", "Binder", "A media to stay", TextHandler.TEXT_MEDIA, "[Media:0]", null, 10, permanentUser); + Binder permanentBinder = portfolioService.assignBinder(permanentUser, templateBinder, templateEntry, null, null); + dbInstance.commitAndCloseSession(); + + // delete the user + userDeletionManager.deleteIdentity(owner); + + // the template is a learn ressource and will not be deleted + Binder reloadedtemplateBinder = portfolioService.getBinderByKey(templateBinder.getKey()); + Assert.assertNotNull(reloadedtemplateBinder); + // the binder + Binder deletedBinder = portfolioService.getBinderByKey(binder.getKey()); + Assert.assertNull(deletedBinder); + // the media + Media deletedMedia = portfolioService.getMediaByKey(media.getKey()); + Assert.assertNull(deletedMedia); + + // check that the method doesn't delete stuff of other users + Binder reloadedPermanentBinder = portfolioService.getBinderByKey(permanentBinder.getKey()); + Assert.assertNotNull(reloadedPermanentBinder); + // the media + Media reloadedPermanentMedia = portfolioService.getMediaByKey(permanentMedia.getKey()); + Assert.assertNotNull(reloadedPermanentMedia); + + } }