From b28db2a88a732fa9faa49b666821e05b184a86a3 Mon Sep 17 00:00:00 2001 From: uhensler <urs.hensler@frentix.com> Date: Fri, 17 May 2019 10:38:34 +0200 Subject: [PATCH] OO-3932: Send a globally unique user id to external editors --- .../doceditor/DocEditorIdentityService.java | 51 +++++++++++++ .../restapi/CollaboraWebService.java | 10 +-- .../manager/DocEditorIdentityServiceImpl.java | 73 +++++++++++++++++++ .../manager/Office365ServiceImpl.java | 2 +- .../restapi/Office365WebService.java | 16 ++-- .../manager/OnlyOfficeServiceImpl.java | 25 ++----- .../manager/DocEditorIdentityServiceTest.java | 52 +++++++++++++ .../java/org/olat/test/AllTestsJunit4.java | 1 + 8 files changed, 201 insertions(+), 29 deletions(-) create mode 100644 src/main/java/org/olat/core/commons/services/doceditor/DocEditorIdentityService.java create mode 100644 src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceImpl.java create mode 100644 src/test/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceTest.java diff --git a/src/main/java/org/olat/core/commons/services/doceditor/DocEditorIdentityService.java b/src/main/java/org/olat/core/commons/services/doceditor/DocEditorIdentityService.java new file mode 100644 index 00000000000..73436de8f8c --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/doceditor/DocEditorIdentityService.java @@ -0,0 +1,51 @@ +/** + * <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; + +import org.olat.core.id.Identity; + +/** + * + * Initial date: 17 May 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public interface DocEditorIdentityService { + + /** + * Get globally unique identity id. + * + * @param identity + * @return + */ + public String getGlobalIdentityId(Identity identity); + + /** + * Get identity by globally unique userId. + * + * + * @param globalIdentityId + * @return + */ + public Identity getIdentity(String globalIdentityId); + + public String getUserDisplayName(Identity identity); + +} diff --git a/src/main/java/org/olat/core/commons/services/doceditor/collabora/restapi/CollaboraWebService.java b/src/main/java/org/olat/core/commons/services/doceditor/collabora/restapi/CollaboraWebService.java index d930b01cafa..01bd52a336d 100644 --- a/src/main/java/org/olat/core/commons/services/doceditor/collabora/restapi/CollaboraWebService.java +++ b/src/main/java/org/olat/core/commons/services/doceditor/collabora/restapi/CollaboraWebService.java @@ -42,13 +42,13 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.apache.logging.log4j.Logger; +import org.olat.core.commons.services.doceditor.DocEditorIdentityService; import org.olat.core.commons.services.doceditor.collabora.CollaboraModule; import org.olat.core.commons.services.doceditor.collabora.CollaboraService; import org.olat.core.commons.services.doceditor.wopi.Access; import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.logging.Tracing; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -72,7 +72,7 @@ public class CollaboraWebService { @Autowired private CollaboraService collaboraService; @Autowired - private UserManager userManager; + private DocEditorIdentityService identityService; @GET @Produces(MediaType.APPLICATION_JSON) @@ -100,13 +100,13 @@ public class CollaboraWebService { } VFSMetadata metadata = access.getMetadata(); - String ownerId = metadata.getAuthor() != null? metadata.getAuthor().getKey().toString(): null; + String ownerId = metadata.getAuthor() != null? identityService.getGlobalIdentityId(metadata.getAuthor()): null; CheckFileInfoVO checkFileInfoVO = CheckFileInfoVO.builder() .withBaseFileName(metadata.getFilename()) // suffix is mandatory .withOwnerId(ownerId) .withSize(metadata.getFileSize()) - .withUserId(access.getIdentity().getKey().toString()) - .withUserFriendlyName(userManager.getUserDisplayName(access.getIdentity())) + .withUserId(identityService.getGlobalIdentityId(access.getIdentity())) + .withUserFriendlyName(identityService.getUserDisplayName(access.getIdentity())) .withVersion(String.valueOf(metadata.getRevisionNr())) .withLastModifiedTime(getAsIso8601(metadata.getLastModified())) .withUserCanWrite(access.isCanEdit()) diff --git a/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceImpl.java new file mode 100644 index 00000000000..5535c39e60d --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceImpl.java @@ -0,0 +1,73 @@ +/** + * <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.manager; + +import org.apache.logging.log4j.Logger; +import org.olat.basesecurity.BaseSecurityManager; +import org.olat.core.commons.services.doceditor.DocEditorIdentityService; +import org.olat.core.id.Identity; +import org.olat.core.logging.Tracing; +import org.olat.core.util.WebappHelper; +import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 17 May 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +@Service +public class DocEditorIdentityServiceImpl implements DocEditorIdentityService { + + private static final Logger log = Tracing.createLoggerFor(DocEditorIdentityServiceImpl.class); + + @Autowired + private BaseSecurityManager securityManager; + @Autowired + private UserManager userManager; + + @Override + public String getGlobalIdentityId(Identity identity) { + return getGlobalUserIdPrefix() + identity.getName(); + } + + @Override + public Identity getIdentity(String globalIdenityId) { + try { + String username = globalIdenityId.substring(getGlobalUserIdPrefix().length()); + return securityManager.findIdentityByNameCaseInsensitive(username); + } catch (NumberFormatException e) { + log.warn("Try to load identity with global unique id " + globalIdenityId, e); + } + return null; + } + + private String getGlobalUserIdPrefix() { + return "openolat." + WebappHelper.getInstanceId() + "."; + } + + @Override + public String getUserDisplayName(Identity identity) { + return userManager.getUserDisplayName(identity); + } + +} diff --git a/src/main/java/org/olat/core/commons/services/doceditor/office365/manager/Office365ServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/office365/manager/Office365ServiceImpl.java index 79a869b6b01..aecbce7ae3b 100644 --- a/src/main/java/org/olat/core/commons/services/doceditor/office365/manager/Office365ServiceImpl.java +++ b/src/main/java/org/olat/core/commons/services/doceditor/office365/manager/Office365ServiceImpl.java @@ -31,6 +31,7 @@ import java.util.Set; import javax.annotation.PostConstruct; +import org.apache.logging.log4j.Logger; import org.olat.core.commons.services.doceditor.DocEditor.Mode; import org.olat.core.commons.services.doceditor.DocEditorSecurityCallback; import org.olat.core.commons.services.doceditor.office365.Office365Module; @@ -45,7 +46,6 @@ import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.control.Event; import org.olat.core.helpers.Settings; import org.olat.core.id.Identity; -import org.apache.logging.log4j.Logger; import org.olat.core.logging.Tracing; import org.olat.core.util.FileUtils; import org.olat.core.util.StringHelper; diff --git a/src/main/java/org/olat/core/commons/services/doceditor/office365/restapi/Office365WebService.java b/src/main/java/org/olat/core/commons/services/doceditor/office365/restapi/Office365WebService.java index af3ac8b23f2..21abe73313d 100644 --- a/src/main/java/org/olat/core/commons/services/doceditor/office365/restapi/Office365WebService.java +++ b/src/main/java/org/olat/core/commons/services/doceditor/office365/restapi/Office365WebService.java @@ -40,15 +40,15 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; +import org.apache.logging.log4j.Logger; +import org.olat.core.commons.services.doceditor.DocEditorIdentityService; import org.olat.core.commons.services.doceditor.office365.Office365Module; import org.olat.core.commons.services.doceditor.office365.Office365Service; import org.olat.core.commons.services.doceditor.wopi.Access; import org.olat.core.commons.services.vfs.VFSMetadata; -import org.apache.logging.log4j.Logger; import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -74,7 +74,7 @@ public class Office365WebService { @Autowired private Office365Service office365Service; @Autowired - private UserManager userManager; + private DocEditorIdentityService identityService; @GET @Produces(MediaType.APPLICATION_JSON) @@ -112,14 +112,18 @@ public class Office365WebService { return Response.serverError().status(Status.NOT_FOUND).build(); } + String userId = identityService.getGlobalIdentityId(access.getIdentity()); VFSMetadata metadata = access.getMetadata(); - String ownerId = metadata.getAuthor() != null? metadata.getAuthor().getKey().toString(): null; + // ownerId is mandatory (this hack seens to work) + String ownerId = metadata.getAuthor() != null + ? identityService.getGlobalIdentityId(metadata.getAuthor()) + : userId; CheckFileInfoVO checkFileInfoVO = CheckFileInfoVO.builder() .withBaseFileName(metadata.getFilename()) // suffix is mandatory .withOwnerId(ownerId) .withSize(metadata.getFileSize()) - .withUserId(access.getIdentity().getKey().toString()) - .withUserFriendlyName(userManager.getUserDisplayName(access.getIdentity())) + .withUserId(userId) + .withUserFriendlyName(identityService.getUserDisplayName(access.getIdentity())) .withVersion(String.valueOf(metadata.getRevisionNr())) .withLastModifiedTime(getAsIso8601(metadata.getLastModified())) .withSupportsGetLock(true) diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java index e3eabd8f645..002cd7f7be8 100644 --- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java +++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java @@ -30,8 +30,9 @@ import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; -import org.olat.basesecurity.BaseSecurityManager; +import org.apache.logging.log4j.Logger; import org.olat.core.commons.services.doceditor.DocEditor.Mode; +import org.olat.core.commons.services.doceditor.DocEditorIdentityService; import org.olat.core.commons.services.doceditor.DocEditorSecurityCallback; import org.olat.core.commons.services.doceditor.onlyoffice.ApiConfig; import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeSecurityService; @@ -46,7 +47,6 @@ import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.helpers.Settings; import org.olat.core.id.Identity; -import org.apache.logging.log4j.Logger; import org.olat.core.logging.Tracing; import org.olat.core.util.FileUtils; import org.olat.core.util.vfs.VFSConstants; @@ -58,7 +58,6 @@ import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.lock.LockInfo; import org.olat.core.util.vfs.lock.LockResult; import org.olat.restapi.security.RestSecurityHelper; -import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -84,13 +83,11 @@ public class OnlyOfficeServiceImpl implements OnlyOfficeService { @Autowired private OnlyOfficeSecurityService onlyOfficeSecurityService; @Autowired + private DocEditorIdentityService identityService; + @Autowired private VFSRepositoryService vfsRepositoryService; @Autowired private VFSLockManager lockManager; - @Autowired - private BaseSecurityManager securityManager; - @Autowired - private UserManager userManager; @Override public boolean fileExists(String fileId) { @@ -142,7 +139,7 @@ public class OnlyOfficeServiceImpl implements OnlyOfficeService { InfoImpl info = new InfoImpl(); String author = vfsMetadata.getAuthor() != null - ? userManager.getUserDisplayName(vfsMetadata.getAuthor()) + ? identityService.getUserDisplayName(vfsMetadata.getAuthor()) : null; info.setAuthor(author); info.setCreated(null); // not in metadata @@ -168,9 +165,9 @@ public class OnlyOfficeServiceImpl implements OnlyOfficeService { apiConfig.setEditor(editorConfig); UserImpl user = new UserImpl(); - String name = userManager.getUserDisplayName(identity); + String name = identityService.getUserDisplayName(identity); user.setName(name); - user.setId(identity.getKey().toString()); + user.setId(identityService.getGlobalIdentityId(identity)); editorConfig.setUser(user); String token = onlyOfficeSecurityService.getApiConfigToken(document, editorConfig); @@ -304,13 +301,7 @@ public class OnlyOfficeServiceImpl implements OnlyOfficeService { @Override public Identity getIdentity(String identityId) { - try { - Long identityKey = Long.valueOf(identityId); - return securityManager.loadIdentityByKey(identityKey); - } catch (NumberFormatException e) { - log.warn("Try to load identity with key " + identityId, e); - } - return null; + return identityService.getIdentity(identityId); } } diff --git a/src/test/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceTest.java b/src/test/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceTest.java new file mode 100644 index 00000000000..4143720d0b1 --- /dev/null +++ b/src/test/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceTest.java @@ -0,0 +1,52 @@ +/** + * <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.manager; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; +import org.olat.core.commons.services.doceditor.DocEditorIdentityService; +import org.olat.core.id.Identity; +import org.olat.test.JunitTestHelper; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 17 May 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class DocEditorIdentityServiceTest extends OlatTestCase { + + @Autowired + private DocEditorIdentityService sut; + + @Test + public void shouldIdentifyIdentityBaGlobalId() { + Identity identity = JunitTestHelper.createAndPersistIdentityAsRndUser("doc-editor-1"); + + String globalUserId = sut.getGlobalIdentityId(identity); + Identity reloadedIdentity = sut.getIdentity(globalUserId); + + assertThat(reloadedIdentity).isEqualTo(identity); + } + +} diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index 374388ab36a..da439120cb9 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -99,6 +99,7 @@ import org.junit.runners.Suite; org.olat.commons.coordinate.cluster.lock.LockTest.class, org.olat.commons.coordinate.CoordinatorTest.class, org.olat.core.commons.services.csp.manager.CSPManagerTest.class, + org.olat.core.commons.services.doceditor.manager.DocEditorIdentityServiceTest.class, org.olat.core.commons.services.doceditor.wopi.manager.AccessDAOTest.class, org.olat.core.commons.services.doceditor.wopi.manager.WopiServiceTest.class, org.olat.core.commons.services.vfs.manager.VFSXStreamTest.class, -- GitLab