From 4f9b882e440a17f358edcd3faa9ea4a60d8dba4f Mon Sep 17 00:00:00 2001 From: Torsten Simon Date: Mon, 21 Oct 2024 09:21:13 +0200 Subject: [PATCH 01/10] fix:clenup & move styles to prevent inline issues --- .../collection-info-bar.component.html | 12 ++---------- .../collection-info-bar.component.scss | 8 ++++++++ .../collections-page/collections-page.component.html | 6 +----- .../collections-page/collections-page.component.scss | 6 ++++++ 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Frontend/src/app/pages/collections-page/collection-info-bar/collection-info-bar.component.html b/Frontend/src/app/pages/collections-page/collection-info-bar/collection-info-bar.component.html index dd82db2b7e..49f8784f58 100644 --- a/Frontend/src/app/pages/collections-page/collection-info-bar/collection-info-bar.component.html +++ b/Frontend/src/app/pages/collections-page/collection-info-bar/collection-info-bar.component.html @@ -8,12 +8,8 @@
-
+
-

+

{{ collection?.title }}

diff --git a/Frontend/src/app/pages/collections-page/collection-info-bar/collection-info-bar.component.scss b/Frontend/src/app/pages/collections-page/collection-info-bar/collection-info-bar.component.scss index 2ebbe1c4a9..2059795bce 100644 --- a/Frontend/src/app/pages/collections-page/collection-info-bar/collection-info-bar.component.scss +++ b/Frontend/src/app/pages/collections-page/collection-info-bar/collection-info-bar.component.scss @@ -36,6 +36,7 @@ overflow-wrap: break-word; line-height: normal; margin: 0; + overflow: hidden; } .collection-new-preview-infoarea { min-height: 120px; @@ -80,6 +81,13 @@ text-align: center; vertical-align: middle; height: 200px; + width: 100%; + .card-collection-image-icon-wrapper { + width: 250px; + height: 200px; + margin-left: auto; + margin-right: auto; + } } .card-image-icon-container { diff --git a/Frontend/src/app/pages/collections-page/collections-page.component.html b/Frontend/src/app/pages/collections-page/collections-page.component.html index df1b79ff15..1ff4266a7d 100644 --- a/Frontend/src/app/pages/collections-page/collections-page.component.html +++ b/Frontend/src/app/pages/collections-page/collections-page.component.html @@ -83,11 +83,7 @@ >
-
+

diff --git a/Frontend/src/app/pages/collections-page/collections-page.component.scss b/Frontend/src/app/pages/collections-page/collections-page.component.scss index 1b953480d1..15ad75514f 100644 --- a/Frontend/src/app/pages/collections-page/collections-page.component.scss +++ b/Frontend/src/app/pages/collections-page/collections-page.component.scss @@ -117,6 +117,12 @@ section { .button-area { text-align: right; } +.collections-right { + .collections-loading-div { + padding-top: 24px; + text-align: center; + } +} .dialog-input { width: 90%; From 6fe6350f295a69a84dfcc4f88cdc9a9e4ee5b702 Mon Sep 17 00:00:00 2001 From: Torsten Simon Date: Mon, 21 Oct 2024 16:55:02 +0200 Subject: [PATCH 02/10] fix:do not allow sys node uuid override via endpoint --- .../edu_sharing/service/collection/CollectionServiceImpl.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/Backend/services/core/src/main/java/org/edu_sharing/service/collection/CollectionServiceImpl.java b/Backend/services/core/src/main/java/org/edu_sharing/service/collection/CollectionServiceImpl.java index 23f22d189f..b093368d0d 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/service/collection/CollectionServiceImpl.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/service/collection/CollectionServiceImpl.java @@ -629,9 +629,6 @@ public void updateAndSetScope(Collection collection) throws Exception { public Map asProps(Collection collection) { Map props = new HashMap<>(); - if (collection.getNodeId() != null) { - props.put(CCConstants.SYS_PROP_NODE_UID, collection.getNodeId()); - } props.put(CCConstants.CM_PROP_TITLE, collection.getTitle()); props.put(CCConstants.CM_NAME, NodeServiceHelper.cleanupCmName(collection.getTitle())); props.put(CCConstants.CM_PROP_DESCRIPTION, collection.getDescription()); From c4010005d96d274cae4bed18b5476b2b7b904c1f Mon Sep 17 00:00:00 2001 From: Torsten Simon Date: Tue, 22 Oct 2024 08:48:02 +0200 Subject: [PATCH 03/10] fix:catch node not found exception when elastic index still holds a deleted collection --- .../collection/CollectionServiceImpl.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Backend/services/core/src/main/java/org/edu_sharing/service/collection/CollectionServiceImpl.java b/Backend/services/core/src/main/java/org/edu_sharing/service/collection/CollectionServiceImpl.java index b093368d0d..d93fffebde 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/service/collection/CollectionServiceImpl.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/service/collection/CollectionServiceImpl.java @@ -7,10 +7,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.repository.AssociationRef; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.repository.*; import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.PermissionService; @@ -843,10 +840,16 @@ protected MCAlfrescoAPIClient.ContextSearchMode getContextModeForScope(String sc } protected boolean isSubCollection(org.edu_sharing.service.model.NodeRef nodeRef) { - return AuthenticationUtil.runAsSystem(() -> { - NodeRef parent = NodeServiceHelper.getPrimaryParent(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeRef.getNodeId())); - return NodeServiceHelper.hasAspect(parent, CCConstants.CCM_ASPECT_COLLECTION); - }); + try { + return AuthenticationUtil.runAsSystem(() -> { + NodeRef parent = NodeServiceHelper.getPrimaryParent(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeRef.getNodeId())); + return NodeServiceHelper.hasAspect(parent, CCConstants.CCM_ASPECT_COLLECTION); + }); + } catch(InvalidNodeRefException e) { + // node from elastic index might already deleted, ignore to prevent full fail of query + logger.info("isSubCollection failed", e); + return true; + } } @Override From 163684b3b68be59f81bb690b129d417073648f19 Mon Sep 17 00:00:00 2001 From: Sebastian Wollner Date: Wed, 23 Oct 2024 08:05:17 +0200 Subject: [PATCH 04/10] fix: sharedForMe shows materials that are not shared yet (timed permission) --- .../service/permission/PermissionServiceHelper.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceHelper.java b/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceHelper.java index aa1ce242d6..0fd5d26b54 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceHelper.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceHelper.java @@ -44,10 +44,12 @@ public PermissionServiceHelper(PermissionService permissionService){ } public static HashSet getExplicitAuthoritiesFromACL(ACL acl) { - return Arrays.stream(acl.getAces()). - filter((ace) -> !ace.isInherited()). - map(ACE::getAuthority). - collect(Collectors.toCollection(HashSet::new)); + return Arrays.stream(acl.getAces()) + .filter((ace) -> !ace.isInherited()) + .filter((ace -> ace.getFrom() == null)) + .filter((ace -> ace.getTo() == null)) + .map(ACE::getAuthority) + .collect(Collectors.toCollection(HashSet::new)); } public static Boolean isNodePublic(NodeRef nodeRef) { From 68b7d6d30d258640a70f53cb55cf8752e3805d0c Mon Sep 17 00:00:00 2001 From: Daniel Rudolph Date: Wed, 23 Oct 2024 15:20:10 +0200 Subject: [PATCH 05/10] feat: embed permission: check permissions for collection and always render original --- .../server/rendering/RenderingServlet.java | 48 ++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/Backend/services/core/src/main/java/org/edu_sharing/repository/server/rendering/RenderingServlet.java b/Backend/services/core/src/main/java/org/edu_sharing/repository/server/rendering/RenderingServlet.java index 52a05bed98..5eec8659e4 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/repository/server/rendering/RenderingServlet.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/repository/server/rendering/RenderingServlet.java @@ -4,6 +4,7 @@ import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; @@ -13,13 +14,17 @@ import org.edu_sharing.repository.server.SecurityHeadersFilter; import org.edu_sharing.repository.server.tools.ApplicationInfoList; import org.edu_sharing.repository.tools.URLHelper; +import org.edu_sharing.service.InsufficientPermissionException; import org.edu_sharing.service.config.ConfigServiceFactory; +import org.edu_sharing.service.nodeservice.NodeServiceHelper; +import org.edu_sharing.service.permission.PermissionChecking; import org.edu_sharing.service.permission.PermissionServiceFactory; import org.edu_sharing.service.rendering.RenderingService; import org.edu_sharing.service.rendering.RenderingServiceFactory; import org.edu_sharing.service.rendering.RenderingTool; import org.edu_sharing.service.tracking.TrackingService; import org.edu_sharing.service.tracking.TrackingServiceFactory; +import org.springframework.web.servlet.support.RequestContextUtils; import java.io.IOException; import java.util.HashMap; @@ -28,10 +33,17 @@ public class RenderingServlet extends HttpServlet { private static final String DEFAULT_DISPLAY_MODE = RenderingTool.DISPLAY_EMBED; private static Logger logger = Logger.getLogger(RenderingServlet.class); + private static PermissionChecking permissionChecking; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + if(permissionChecking == null) { + // @TODO: Is there a more streamlined way? + permissionChecking = RequestContextUtils.findWebApplicationContext(req).getBean("permissionChecking", PermissionChecking.class); + } + // new, preferred parameter String node_id = req.getParameter("nodeId"); if(node_id == null) { @@ -66,17 +78,20 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) resp.getWriter().write(""); String response; try { - if(!PermissionServiceFactory.getLocalService().hasPermission(StoreRef.PROTOCOL_WORKSPACE, + /*if(!PermissionServiceFactory.getLocalService().hasPermission(StoreRef.PROTOCOL_WORKSPACE, StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier(), node_id, CCConstants.PERMISSION_EMBED)){ throw new AccessDeniedException(CCConstants.PERMISSION_EMBED); + }*/ + String original = checkAndGetCollectionRef(node_id); + if(original != null) { + response = AuthenticationUtil.runAsSystem(() -> renderInternal(renderingService,original,version,params)); + }else { + response = renderInternal(renderingService,original,version,params); } - response = renderingService.getDetails(ApplicationInfoList.getHomeRepository().getAppId(), node_id, version,DEFAULT_DISPLAY_MODE, params).getDetails(); - response = response.replace("{{{LMS_INLINE_HELPER_SCRIPT}}}", URLHelper.getNgRenderNodeUrl(node_id,version)+"?"); - // add nonce to render styles - response = response.replace(""); resp.getWriter().write(""); } + + private String renderInternal(RenderingService renderingService, String node_id, String version, Map params) throws Exception { + String response = renderingService.getDetails(ApplicationInfoList.getHomeRepository().getAppId(), node_id, version,DEFAULT_DISPLAY_MODE, params).getDetails(); + response = response.replace("{{{LMS_INLINE_HELPER_SCRIPT}}}", URLHelper.getNgRenderNodeUrl(node_id,version)+"?"); + // add nonce to render styles + response = response.replace(" Date: Wed, 23 Oct 2024 16:09:21 +0200 Subject: [PATCH 06/10] i18n:en DESP-25 --- Frontend/src/assets/i18n/workspace/en.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Frontend/src/assets/i18n/workspace/en.json b/Frontend/src/assets/i18n/workspace/en.json index 1f5bc23a92..343494be80 100644 --- a/Frontend/src/assets/i18n/workspace/en.json +++ b/Frontend/src/assets/i18n/workspace/en.json @@ -514,6 +514,13 @@ "VIRTUAL": "You're inside a folder where inserting elements is not possible.", "GENERAL": "Navigate to a different folder and create your elements there." }, + "COPY_MOVE": { + "TITLE": "Move/copy element(s)", + "MESSAGE_SINGLE": "Do you want to move/copy \"{{element}}\" from \"{{source}}\" to \"{{target}}\"?", + "MESSAGE_MULTIPLE": "Do you want to move/copy {{count}} elements from \"{{source}}\" to \"{{target}}\"?", + "MOVE": "Move", + "COPY": "Copy" + }, "TOAST": { "FOLDER_ADDED": "Folder added", "NODE_EXISTS_IN_COLLECTION": "The collection already contains the element {{name}}", From 6bbdaf492ff32677311d2e2366ad8c9c5141a15a Mon Sep 17 00:00:00 2001 From: Torsten Simon Date: Wed, 23 Oct 2024 16:29:35 +0200 Subject: [PATCH 07/10] feat:allow config for non-fuzzy group search parameter --- .../service/permission/PermissionServiceImpl.java | 2 +- .../src/main/resources/edu-sharing.reference.conf | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceImpl.java b/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceImpl.java index 8ae4db6eeb..6613fa6a0a 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceImpl.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/service/permission/PermissionServiceImpl.java @@ -1108,7 +1108,7 @@ public StringBuffer getFindGroupsSearchString(String searchWord, boolean globalC } if (!token.isEmpty()) { - subQuery.append("=@cm:authorityDisplayName:").append("\"").append(token).append("\""); + subQuery.append(LightbendConfigLoader.get().getString("repository.search.groups.nonFuzzyField")).append(":\"").append(token).append("\""); } // if not fuzzy and no value for email return empty result diff --git a/config/defaults/src/main/resources/edu-sharing.reference.conf b/config/defaults/src/main/resources/edu-sharing.reference.conf index 08b318a0a1..872b6d10ef 100644 --- a/config/defaults/src/main/resources/edu-sharing.reference.conf +++ b/config/defaults/src/main/resources/edu-sharing.reference.conf @@ -539,6 +539,16 @@ repository: { ] } + // search related configs for queries which are not handled by the mds + search { + // groups related search configs + groups: { + // field/solr key to match when non fuzzy group search is enabled + // examples: "=@cm:authorityDisplayName", "=@ccm:groupEmail" + nonFuzzyField: "=@cm:authorityDisplayName" + } + } + webdav: { enabled: true authentication: { From b71845dffa10c5604a61103f6691a692d0a1b7c5 Mon Sep 17 00:00:00 2001 From: Torsten Simon Date: Wed, 23 Oct 2024 16:29:54 +0200 Subject: [PATCH 08/10] fix:model ccm:groupEmail is broken cause of "both" tokenisation issue in alfresco 23 --- .../main/amp/config/alfresco/extension/es_models/ccmodel.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Backend/alfresco/module/src/main/amp/config/alfresco/extension/es_models/ccmodel.xml b/Backend/alfresco/module/src/main/amp/config/alfresco/extension/es_models/ccmodel.xml index 0f968ae1a6..8a69f7e5a8 100644 --- a/Backend/alfresco/module/src/main/amp/config/alfresco/extension/es_models/ccmodel.xml +++ b/Backend/alfresco/module/src/main/amp/config/alfresco/extension/es_models/ccmodel.xml @@ -1834,7 +1834,8 @@ true false - both + + false From 8aa12f313da60e8fde4f2dfa4192b1e90005335a Mon Sep 17 00:00:00 2001 From: Daniel Rudolph Date: Wed, 23 Oct 2024 21:10:20 +0200 Subject: [PATCH 09/10] feat: embed permission: revert always render original --- .../server/rendering/RenderingServlet.java | 59 +++++++------------ 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/Backend/services/core/src/main/java/org/edu_sharing/repository/server/rendering/RenderingServlet.java b/Backend/services/core/src/main/java/org/edu_sharing/repository/server/rendering/RenderingServlet.java index 5eec8659e4..f86d5efd20 100644 --- a/Backend/services/core/src/main/java/org/edu_sharing/repository/server/rendering/RenderingServlet.java +++ b/Backend/services/core/src/main/java/org/edu_sharing/repository/server/rendering/RenderingServlet.java @@ -10,6 +10,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; +import org.edu_sharing.alfresco.RestrictedAccessException; import org.edu_sharing.repository.client.tools.CCConstants; import org.edu_sharing.repository.server.SecurityHeadersFilter; import org.edu_sharing.repository.server.tools.ApplicationInfoList; @@ -33,17 +34,11 @@ public class RenderingServlet extends HttpServlet { private static final String DEFAULT_DISPLAY_MODE = RenderingTool.DISPLAY_EMBED; private static Logger logger = Logger.getLogger(RenderingServlet.class); - private static PermissionChecking permissionChecking; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - if(permissionChecking == null) { - // @TODO: Is there a more streamlined way? - permissionChecking = RequestContextUtils.findWebApplicationContext(req).getBean("permissionChecking", PermissionChecking.class); - } - // new, preferred parameter String node_id = req.getParameter("nodeId"); if(node_id == null) { @@ -78,20 +73,27 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) resp.getWriter().write(""); String response; try { - /*if(!PermissionServiceFactory.getLocalService().hasPermission(StoreRef.PROTOCOL_WORKSPACE, - StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier(), - node_id, - CCConstants.PERMISSION_EMBED)){ - throw new AccessDeniedException(CCConstants.PERMISSION_EMBED); - }*/ - String original = checkAndGetCollectionRef(node_id); - if(original != null) { - response = AuthenticationUtil.runAsSystem(() -> renderInternal(renderingService,original,version,params)); - }else { - response = renderInternal(renderingService,original,version,params); + NodeRef ref = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, node_id); + if(NodeServiceHelper.hasAspect(ref,CCConstants.CCM_ASPECT_COLLECTION_IO_REFERENCE)){ + try { + NodeServiceHelper.validatePermissionRestrictedAccess(ref, CCConstants.PERMISSION_READ_ALL, CCConstants.PERMISSION_EMBED); + } catch (RestrictedAccessException e) { + throw new AccessDeniedException(CCConstants.PERMISSION_EMBED); + } + }else{ + if(!PermissionServiceFactory.getLocalService().hasPermission(ref.getStoreRef().getProtocol(), + ref.getStoreRef().getIdentifier(), + node_id, + CCConstants.PERMISSION_EMBED)) { + throw new AccessDeniedException(CCConstants.PERMISSION_EMBED); + } } - + response = renderingService.getDetails(ApplicationInfoList.getHomeRepository().getAppId(), node_id, version,DEFAULT_DISPLAY_MODE, params).getDetails(); + response = response.replace("{{{LMS_INLINE_HELPER_SCRIPT}}}", URLHelper.getNgRenderNodeUrl(node_id,version)+"?"); + // add nonce to render styles + response = response.replace(""); resp.getWriter().write(""); } - - private String renderInternal(RenderingService renderingService, String node_id, String version, Map params) throws Exception { - String response = renderingService.getDetails(ApplicationInfoList.getHomeRepository().getAppId(), node_id, version,DEFAULT_DISPLAY_MODE, params).getDetails(); - response = response.replace("{{{LMS_INLINE_HELPER_SCRIPT}}}", URLHelper.getNgRenderNodeUrl(node_id,version)+"?"); - // add nonce to render styles - response = response.replace(" Date: Thu, 24 Oct 2024 11:09:17 +0200 Subject: [PATCH 10/10] fix:cleanup layout for add to group --- .../authorities/authorities.component.scss | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/Frontend/src/app/pages/user-management-page/authorities/authorities.component.scss b/Frontend/src/app/pages/user-management-page/authorities/authorities.component.scss index d91ba0e5d4..44ef14f7b4 100644 --- a/Frontend/src/app/pages/user-management-page/authorities/authorities.component.scss +++ b/Frontend/src/app/pages/user-management-page/authorities/authorities.component.scss @@ -163,7 +163,7 @@ color: $primary; } -$addToWidth: 400px; +$addToWidth: 450px; .list { overflow-y: auto; position: fixed; @@ -177,11 +177,6 @@ $addToWidth: 400px; width: 100%; } } -.listEmbedded { - top: 270px; - height: calc(100% - 330px); - width: $addToWidth; -} .formEmbedded { width: $addToWidth; } @@ -198,8 +193,8 @@ label.search { position: fixed; right: 0; width: $addToWidth; - top: calc(115px + var(--mainnavHeight)); - height: calc(100% - 115px - var(--mainnavHeight)); + top: calc(105px + var(--mainnavHeight)); + height: calc(100% - 105px - var(--mainnavHeight)); z-index: 2; padding-bottom: 20px; background-color: #fff; @@ -212,7 +207,27 @@ label.search { } .addToList { height: calc(100% - 37px); - overflow-y: auto; + // overflow-y: auto; + ::ng-deep es-permissions-authorities { + height: calc(100% - 7px); + display: flex; + flex-direction: column; + .topFrame { + display: none; + } + .searchEmbedded { + .mat-mdc-form-field-subscript-wrapper { + display: none; + } + } + .list { + position: relative; + top: 0; + height: auto; + flex-grow: 1; + overflow-y: auto; + } + } } #groupType { margin-bottom: 20px;