diff --git a/src/main/java/org/olat/core/commons/services/_spring/servicesCorecontext.xml b/src/main/java/org/olat/core/commons/services/_spring/servicesCorecontext.xml index ab7ab2d7628be12e241b7c58665f3d4d15ef08e1..603257c3149e46053e7edf9e5706a87e3779b653 100644 --- a/src/main/java/org/olat/core/commons/services/_spring/servicesCorecontext.xml +++ b/src/main/java/org/olat/core/commons/services/_spring/servicesCorecontext.xml @@ -10,7 +10,7 @@ <context:component-scan base-package="org.olat.core.commons.services" /> - <import resource="classpath:/org/olat/core/commons/services/jmx/_spring/jmxContext.xml"/> + <import resource="classpath:/org/olat/core/commons/services/jmx/_spring/jmxContext.xml"/> <import resource="classpath:/org/olat/core/commons/services/scheduler/_spring/schedulerContext.xml"/> <import resource="classpath:/org/olat/core/commons/services/taskexecutor/_spring/taskExecutorCorecontext.xml"/> <import resource="classpath:/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml"/> @@ -47,13 +47,13 @@ </bean> </property> <property name="navigationKey" value="analytics" /> - <property name="parentTreeNodeIdentifier" value="externalToolsParent" /> + <property name="parentTreeNodeIdentifier" value="externalToolsParent" /> <property name="i18nActionKey" value="admin.menu.title"/> <property name="i18nDescriptionKey" value="admin.menu.title.alt"/> <property name="translationPackage" value="org.olat.core.commons.services.analytics.ui"/> <property name="extensionPoints"> <list> - <value>org.olat.admin.SystemAdminMainController</value> + <value>org.olat.admin.SystemAdminMainController</value> </list> </property> </bean> @@ -67,13 +67,13 @@ </bean> </property> <property name="navigationKey" value="license" /> - <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> <property name="i18nActionKey" value="admin.menu.title"/> <property name="i18nDescriptionKey" value="admin.menu.title.alt"/> <property name="translationPackage" value="org.olat.core.commons.services.license.ui"/> <property name="extensionPoints"> <list> - <value>org.olat.admin.SystemAdminMainController</value> + <value>org.olat.admin.SystemAdminMainController</value> </list> </property> </bean> @@ -90,10 +90,10 @@ <property name="translationPackage" value="org.olat.admin" /> <property name="i18nActionKey" value="menu.versions"/> <property name="i18nDescriptionKey" value="menu.versions.alt"/> - <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> <property name="extensionPoints"> <list> - <value>org.olat.admin.SystemAdminMainController</value> + <value>org.olat.admin.SystemAdminMainController</value> </list> </property> </bean> @@ -107,18 +107,18 @@ </bean> </property> <property name="navigationKey" value="pdfservice" /> - <property name="parentTreeNodeIdentifier" value="externalToolsParent" /> + <property name="parentTreeNodeIdentifier" value="externalToolsParent" /> <property name="i18nActionKey" value="admin.menu.title"/> <property name="i18nDescriptionKey" value="admin.menu.title.alt"/> <property name="translationPackage" value="org.olat.core.commons.services.pdf.ui"/> <property name="extensionPoints"> <list> - <value>org.olat.admin.SystemAdminMainController</value> + <value>org.olat.admin.SystemAdminMainController</value> </list> </property> </bean> - <!-- Collabora admin. panel --> + <!-- Document editor admin. panel --> <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> <property name="order" value="8256" /> <property name="actionController"> @@ -133,20 +133,31 @@ <property name="parentTreeNodeIdentifier" value="externalToolsParent" /> <property name="extensionPoints"> <list> - <value>org.olat.admin.SystemAdminMainController</value> + <value>org.olat.admin.SystemAdminMainController</value> </list> </property> </bean> + <!-- Cleaning job for WOPI access --> + <bean id="wopiDeleteExpiredAccessJob" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> + <property name="jobDetail"> + <bean class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> + <property name="jobClass" value="org.olat.core.commons.services.doceditor.wopi.manager.WopiDeleteExpiredAccessJob" /> + </bean> + </property> + <property name="cronExpression" value="0 23 4 * * ?"/> + <property name="startDelay" value="45000" /> + </bean> + <!-- Cleaning job for CSP reports --> <bean id="cspCleanupJob" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail"> - <bean class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> + <bean class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="org.olat.core.commons.services.csp.manager.CSPLogCleanup" /> </bean> - </property> - <property name="cronExpression" value="0 0 4 * * ?"/><!-- 2am, daily --> - <property name="startDelay" value="45000" /> + </property> + <property name="cronExpression" value="0 0 4 * * ?"/><!-- 2am, daily --> + <property name="startDelay" value="45000" /> </bean> </beans> \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/services/doceditor/wopi/manager/AccessDAO.java b/src/main/java/org/olat/core/commons/services/doceditor/wopi/manager/AccessDAO.java index 2e182747dd5cd4cc1534e978dd279d34c3a4e5c1..3dc9e7ba5863869ad2cd53c08fe6ed8b1cb87a72 100644 --- a/src/main/java/org/olat/core/commons/services/doceditor/wopi/manager/AccessDAO.java +++ b/src/main/java/org/olat/core/commons/services/doceditor/wopi/manager/AccessDAO.java @@ -129,6 +129,19 @@ class AccessDAO { .setParameter("token", token) .executeUpdate(); } + + void deleteExpired(Date before) { + if (before == null) return; + + QueryBuilder sb = new QueryBuilder(); + sb.append("delete from wopiaccess access"); + sb.and().append("access.expiresAt < :before"); + + dbInstance.getCurrentEntityManager() + .createQuery(sb.toString()) + .setParameter("before", before) + .executeUpdate(); + } void deleteAll() { dbInstance.getCurrentEntityManager() diff --git a/src/main/java/org/olat/core/commons/services/doceditor/wopi/manager/WopiDeleteExpiredAccessJob.java b/src/main/java/org/olat/core/commons/services/doceditor/wopi/manager/WopiDeleteExpiredAccessJob.java new file mode 100644 index 0000000000000000000000000000000000000000..3442efcab1004243f4b94c064110b9715b0e899a --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/doceditor/wopi/manager/WopiDeleteExpiredAccessJob.java @@ -0,0 +1,44 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.doceditor.wopi.manager; + +import java.util.Date; + +import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.scheduler.JobWithDB; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +/** + * + * Initial date: 6 May 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class WopiDeleteExpiredAccessJob extends JobWithDB { + + @Override + public void executeWithDB(JobExecutionContext arg0) throws JobExecutionException { + AccessDAO accessDAO = CoreSpringFactory.getImpl(AccessDAO.class); + Date now = new Date(); + accessDAO.deleteExpired(now); + } + +} diff --git a/src/test/java/org/olat/core/commons/services/doceditor/wopi/manager/AccessDAOTest.java b/src/test/java/org/olat/core/commons/services/doceditor/wopi/manager/AccessDAOTest.java index 5f9ed5b77d2970765fde5f334021c2ead03af51b..be60bd20a13f16aaab1640cc8bb1c0e8adccf1a7 100644 --- a/src/test/java/org/olat/core/commons/services/doceditor/wopi/manager/AccessDAOTest.java +++ b/src/test/java/org/olat/core/commons/services/doceditor/wopi/manager/AccessDAOTest.java @@ -108,7 +108,7 @@ public class AccessDAOTest extends OlatTestCase { Access createdAccess = createRandomAccess(); dbInstance.commitAndCloseSession(); - Access reloadedAccess = sut.loadAccess(createdAccess.getToken()); + Access reloadedAccess = reload(createdAccess); assertThat(reloadedAccess).isEqualTo(createdAccess); } @@ -142,10 +142,39 @@ public class AccessDAOTest extends OlatTestCase { sut.deleteAccess(createdAccess.getToken()); dbInstance.commitAndCloseSession(); - Access reloadedAccess = sut.loadAccess(createdAccess.getToken()); + Access reloadedAccess = reload(createdAccess); assertThat(reloadedAccess).isNull(); } + @Test + public void shouldDeleteExpired() { + Identity identity = JunitTestHelper.createAndPersistIdentityAsRndUser("wopi"); + VFSMetadata vfsMetadata = vfsMetadataDAO.createMetadata(random(), "relPath", "file.name", new Date(), 1000l, false, "", "file", null); + Date twoDaysAgo = Date.from(Instant.now().minus(Duration.ofDays(2)));; + Access expiredTwoDaysAgo = sut.createAccess(vfsMetadata, identity, random(), random(), true, true, true, twoDaysAgo); + Date oneDayAgo = Date.from(Instant.now().minus(Duration.ofDays(1)));; + Access expiredOneDayAgo = sut.createAccess(vfsMetadata, identity, random(), random(), true, true, true, oneDayAgo); + Date inOneDay = Date.from(Instant.now().plus(Duration.ofDays(1)));; + Access expiresInOneDay = sut.createAccess(vfsMetadata, identity, random(), random(), true, true, true, inOneDay); + Access noExpiration = sut.createAccess(vfsMetadata, identity, random(), random(), true, true, true, null); + dbInstance.commitAndCloseSession(); + + Date now = new Date(); + sut.deleteExpired(now); + dbInstance.commitAndCloseSession(); + + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(reload(expiredOneDayAgo)).isNull(); + softly.assertThat(reload(expiredTwoDaysAgo)).isNull(); + softly.assertThat(reload(expiresInOneDay)).isNotNull(); + softly.assertThat(reload(noExpiration)).isNotNull(); + softly.assertAll(); + } + + private Access reload(Access access) { + return sut.loadAccess(access.getToken()); + } + private Access createRandomAccess() { Identity identity = JunitTestHelper.createAndPersistIdentityAsRndUser("wopi"); VFSMetadata vfsMetadata = vfsMetadataDAO.createMetadata(random(), "relPath", "file.name", new Date(), 1000l, false, "", "file", null);