Uploaded image for project: 'CMS'
  1. CMS
  2. CMS-7219

Read more link on contents which are on restricted pages

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Major Major
    • 3.8.1, 4.0M6
    • 3.7.3
    • None
    • None

      I have a content displayed on several pages in main view.
      All these pages are restricted for different group of users.
      The index page is accessible to all authenticated users.
      On the index page, there are filtered contents service with the option to take account of user rights.

      The good contents are returned but the wrong link to the main view of the content is returned.

      For example, we have a content in main view on page1 and page2. The page1 is restricted to students and the page2 is restricted to personal. The content is showing by the filtered contents service but on display, this is the first page of the list where the content is displayed in main view which is displayed. It doesn't take care of the restricted access on linked pages.

      If you display a content in abstract or link view on the index page, it's the same behavior.

      For carousel, we have found a work around. But what about the other cases ?

          [CMS-7219] Read more link on contents which are on restricted pages

          To fix it :

          • The method accessibleReferencedPages has been added to AmetysXSLTHelper
            <xsl:variable name="accessible-pages" select="ametys:accessibleReferencedPages($contentId)"/>
            
          • The method return a node list with the id of accessible pages and their metadata set as following :
            <page id="page://xxxxxx" metadataSetName="main"/>
            <page id="page://yyyyy" metadataSetName="main"/>
            
          • The XSL template common-content-body-readmore for the link "read more" of a content, use this helper, on a filtered content service only and if check user access is needed

          NB: accessibleReferencedPages returns all referenced pages without checking user access on back-office

          Laurence Aumeunier added a comment - To fix it : The method accessibleReferencedPages has been added to AmetysXSLTHelper < xsl:variable name= "accessible-pages" select= "ametys:accessibleReferencedPages($contentId)" /> The method return a node list with the id of accessible pages and their metadata set as following : <page id= "page://xxxxxx" metadataSetName= "main" /> <page id= "page://yyyyy" metadataSetName= "main" /> The XSL template common-content-body-readmore for the link "read more" of a content, use this helper, on a filtered content service only and if check user access is needed NB: accessibleReferencedPages returns all referenced pages without checking user access on back-office

          Bérénice Maurel added a comment - - edited

          We have made a RestrictPageHelper :

          import java.util.Collection;
          import java.util.LinkedList;
          
          import org.ametys.cms.transformation.xslt.ResolveURIComponent;
          import org.ametys.plugins.repository.AmetysObjectResolver;
          import org.ametys.web.WebConstants;
          import org.ametys.web.pageaccess.PageAccessManager;
          import org.ametys.web.repository.content.WebContent;
          import org.ametys.web.repository.page.Page;
          import org.ametys.web.repository.page.ZoneItem;
          import org.apache.avalon.framework.context.Context;
          import org.apache.avalon.framework.context.ContextException;
          import org.apache.avalon.framework.context.Contextualizable;
          import org.apache.avalon.framework.service.ServiceException;
          import org.apache.avalon.framework.service.ServiceManager;
          import org.apache.avalon.framework.service.Serviceable;
          import org.apache.cocoon.components.ContextHelper;
          
          /**
           * Operation on restrict pages.
           * 
           * @author Bérénice MAUREL
           *
           */
          public class RestrictPageHelper implements Contextualizable, Serviceable
          {
              private static PageAccessManager _accessManager;
              private static AmetysObjectResolver _ametysObjectResolver;
              private static Context _context;
          
              @Override
              public void service(ServiceManager manager) throws ServiceException
              {
                  _accessManager = (PageAccessManager) manager.lookup(PageAccessManager.ROLE);
                  _ametysObjectResolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
              }
          
              @Override
              public void contextualize(Context context) throws ContextException
              {
                  _context = context;
              }
              
              /**
               * Get an accessible page where the content is, metadataSet main in priority.
               * @param contentId Content to analyze
               * @return URI if a page is found, otherwise an empty String
               */
              public static String getAccessiblePage(String contentId)
              {
                  WebContent content = _ametysObjectResolver.resolveById(contentId);
                  
                  Collection<ZoneItem> zoneItems = content.getReferencingZoneItems();
                  LinkedList<Page> pages = new LinkedList<Page>();
                  for (ZoneItem zoneItem : zoneItems)
                  {
                      Page page = zoneItem.getZone().getPage();
                      boolean isInList = pages.contains(page);
                      if (zoneItem.getMetadataSetName().equals("main"))
                      {
                          if (isInList)
                          {
                              pages.remove(page);
                          }
                          pages.addFirst(zoneItem.getZone().getPage());
                      }
                      else if (!isInList)
                      {
                          pages.add(page);
                      }
                  }
                  
                  String login = (String) ContextHelper.getRequest(_context).getAttribute(WebConstants.FO_LOGIN);
                  
                  for (Page page : pages)
                  {
                      if (_accessManager.hasRight(page, login))
                      {
                          return ResolveURIComponent.resolve("page", page.getId(), false);
                      }
                  }
                  
                  return "";
              }
          }

          And we declare a component for this helper in a plugin.xml in the project.

          Then we get the page URI like this in the carousel, instead-of getting the page-id returned by the content view in the meta tags :

          <xsl:variable name="page-uri" select="restrict:getAccessiblePage(@id)"/>

          Old version :

          <xsl:variable name="page-uri" select="resolver:resolve('page', html/head/meta[@name = 'pages/page;id']/@content, false)"/>

          Bérénice Maurel added a comment - - edited We have made a RestrictPageHelper : import java.util.Collection; import java.util.LinkedList; import org.ametys.cms.transformation.xslt.ResolveURIComponent; import org.ametys.plugins.repository.AmetysObjectResolver; import org.ametys.web.WebConstants; import org.ametys.web.pageaccess.PageAccessManager; import org.ametys.web.repository.content.WebContent; import org.ametys.web.repository.page.Page; import org.ametys.web.repository.page.ZoneItem; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.service.ServiceManager; import org.apache.avalon.framework.service.Serviceable; import org.apache.cocoon.components.ContextHelper; /** * Operation on restrict pages. * * @author Bérénice MAUREL * */ public class RestrictPageHelper implements Contextualizable, Serviceable { private static PageAccessManager _accessManager; private static AmetysObjectResolver _ametysObjectResolver; private static Context _context; @Override public void service(ServiceManager manager) throws ServiceException { _accessManager = (PageAccessManager) manager.lookup(PageAccessManager.ROLE); _ametysObjectResolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); } @Override public void contextualize(Context context) throws ContextException { _context = context; } /** * Get an accessible page where the content is, metadataSet main in priority. * @param contentId Content to analyze * @ return URI if a page is found, otherwise an empty String */ public static String getAccessiblePage( String contentId) { WebContent content = _ametysObjectResolver.resolveById(contentId); Collection<ZoneItem> zoneItems = content.getReferencingZoneItems(); LinkedList<Page> pages = new LinkedList<Page>(); for (ZoneItem zoneItem : zoneItems) { Page page = zoneItem.getZone().getPage(); boolean isInList = pages.contains(page); if (zoneItem.getMetadataSetName().equals( "main" )) { if (isInList) { pages.remove(page); } pages.addFirst(zoneItem.getZone().getPage()); } else if (!isInList) { pages.add(page); } } String login = ( String ) ContextHelper.getRequest(_context).getAttribute(WebConstants.FO_LOGIN); for (Page page : pages) { if (_accessManager.hasRight(page, login)) { return ResolveURIComponent.resolve( "page" , page.getId(), false ); } } return ""; } } And we declare a component for this helper in a plugin.xml in the project. Then we get the page URI like this in the carousel, instead-of getting the page-id returned by the content view in the meta tags : < xsl:variable name= "page-uri" select= "restrict:getAccessiblePage(@id)" /> Old version : < xsl:variable name= "page-uri" select= "resolver:resolve( 'page' , html/head/meta[@name = 'pages/page;id' ]/@content, false)" />

          Which is the work around ?

          Laurence Aumeunier added a comment - Which is the work around ?

            laurence Laurence Aumeunier
            bmaurel Bérénice Maurel
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: