From 448224e228892703f99c38f88d52d3b7e9efeb8b Mon Sep 17 00:00:00 2001 From: atos-mohamed-b <126660650+atos-mohamed-b@users.noreply.github.com> Date: Mon, 10 Feb 2025 12:23:16 +0100 Subject: [PATCH] LUT-27605: Use forms' workgroups to restrict their access (and the access to their responses) to users part of the same workgroups --- .../business/form/list/FormListFacade.java | 27 +++++ .../business/form/list/FormListLuceneDAO.java | 114 ++++++++++++++++++ .../business/form/list/IFormListDAO.java | 22 ++++ .../initializer/IFormPanelInitializer.java | 10 ++ .../FormPanelFormResponseInitializer.java | 7 ++ .../impl/FormPanelFormsInitializer.java | 7 ++ ...PanelFormResponseInitializerQueryPart.java | 11 ++ .../FormPanelFormsInitializerQueryPart.java | 46 +++++++ .../FormsMultiviewAuthorizationService.java | 18 +++ .../IFormsMultiviewAuthorizationService.java | 14 +++ .../forms/service/MultiviewFormService.java | 78 +++++++++++- .../MultiviewFormResponseDetailsJspBean.java | 8 ++ .../web/admin/MultiviewFormsJspBean.java | 4 +- .../display/impl/FormFilterDisplayForms.java | 7 +- .../business/form/list/FormListDAOMock.java | 18 +++ .../FormPanelFormResponseInitializerMock.java | 7 ++ .../impl/FormPanelFormsInitializerMock.java | 7 ++ 17 files changed, 397 insertions(+), 8 deletions(-) diff --git a/src/java/fr/paris/lutece/plugins/forms/business/form/list/FormListFacade.java b/src/java/fr/paris/lutece/plugins/forms/business/form/list/FormListFacade.java index 3979ba5e3..1d3d11f41 100644 --- a/src/java/fr/paris/lutece/plugins/forms/business/form/list/FormListFacade.java +++ b/src/java/fr/paris/lutece/plugins/forms/business/form/list/FormListFacade.java @@ -33,6 +33,7 @@ */ package fr.paris.lutece.plugins.forms.business.form.list; +import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.forms.business.form.FormItemSortConfig; import java.util.Comparator; import java.util.List; @@ -88,4 +89,30 @@ public void populateFormColumns( FormPanel formPanel, List listForm _formListDAO.populateFormColumns( formPanel, listFormColumn, listFormFilter, nStartIndex, nPageSize, sortConfig ); } + + /** + * Populate the given FormPanel with the information of the given FormColumns and FormFilters + * + * @param formPanel + * The FormPanel to populate + * @param listFormColumn + * The list of all FormColumn to use to be populated + * @param listFormFilter + * The list of FormFilter to use for retrieving the data of the columns to populate + * @param nStartIndex + * The start index of doc + * @param nPageSize + * The number of docs to load for pagination purpose + * @param sortConfig + * The comparator config + * @param user + * The current user + */ + public void populateFormColumns( FormPanel formPanel, List listFormColumn, List listFormFilter, int nStartIndex, int nPageSize, + FormItemSortConfig sortConfig, User user ) + { + listFormColumn.sort( Comparator.comparing( IFormColumn::getFormColumnPosition ) ); + + _formListDAO.populateFormColumns( formPanel, listFormColumn, listFormFilter, nStartIndex, nPageSize, sortConfig, user ); + } } diff --git a/src/java/fr/paris/lutece/plugins/forms/business/form/list/FormListLuceneDAO.java b/src/java/fr/paris/lutece/plugins/forms/business/form/list/FormListLuceneDAO.java index 9bd43e618..95eac2812 100644 --- a/src/java/fr/paris/lutece/plugins/forms/business/form/list/FormListLuceneDAO.java +++ b/src/java/fr/paris/lutece/plugins/forms/business/form/list/FormListLuceneDAO.java @@ -41,6 +41,7 @@ import fr.paris.lutece.plugins.forms.business.form.FormParameters; import fr.paris.lutece.plugins.forms.business.form.FormResponseItem; +import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.forms.business.form.FormItemSortConfig; import fr.paris.lutece.plugins.forms.business.form.column.FormColumnCell; import fr.paris.lutece.plugins.forms.business.form.column.IFormColumn; @@ -85,6 +86,22 @@ public void populateFormColumns( FormPanel formPanel, List listForm formPanel.setFormResponseItemList( listFormResponseItem ); } + @Override + public void populateFormColumns( FormPanel formPanel, List listFormColumn, List listFormFilter, int nStartIndex, int nPageSize, + FormItemSortConfig sortConfig, User user ) + { + // To retrieve the values to display on the table we must have a FormPanel and a list of FormColumn + if ( formPanel == null || CollectionUtils.isEmpty( listFormColumn ) ) + { + return; + } + + List listFormResponseItem = searchFormResponseItem( formPanel, listFormColumn, listFormFilter, nStartIndex, nPageSize, sortConfig, + user ); + + formPanel.setFormResponseItemList( listFormResponseItem ); + } + @Override public List searchAllFormResponseItem( FormPanel formPanel, List listFormColumn, List listFormFilter, FormItemSortConfig sortConfig ) @@ -122,6 +139,103 @@ private List searchFormResponseItem( FormPanel formPanel, List return listFormResponseItem; } + private List searchFormResponseItem( FormPanel formPanel, List listFormColumn, List listFormFilter, + int nStartIndex, int nPageSize, FormItemSortConfig sortConfig, User user ) + { + // Create the list of all values of the parameter to used + List listQueryParametersValues = new ArrayList<>( ); + + // Build the list of query part from the formPanel, the list of columns and the list of filters + List listFormPanelInitializerQueryPart = buildFormPanelInitializerQueryPartList( formPanel, listQueryParametersValues, + user ); + List listFormColumnQueryPart = buildformColumnQueryPartList( listFormColumn ); + List listFormFilterQueryPart = buildFormFilterQueryPartList( listFormFilter, listQueryParametersValues ); + + List listFormResponseItem = new ArrayList<>( ); + + for ( FormResponseSearchItem formResponseSearchItem : _formSearchEngine.getSearchResults( listFormPanelInitializerQueryPart, listFormColumnQueryPart, + listFormFilterQueryPart, sortConfig, nStartIndex, nPageSize, formPanel ) ) + { + // Create a FormResponseItem for the current result line + FormResponseItem formResponseItem = createFormResponseItem( formResponseSearchItem ); + listFormResponseItem.add( formResponseItem ); + + for ( IFormColumnQueryPart formColumnQueryPart : listFormColumnQueryPart ) + { + FormColumnCell formColumnCell = formColumnQueryPart.getFormColumnCell( formResponseSearchItem ); + formResponseItem.addFormColumnCell( formColumnCell ); + } + } + return listFormResponseItem; + } + + /** + * Build the list of all FormPanelInitializerQueryPart associate to all the FormPanelInitializer to retrieve from the given FormPanel + * + * @param formPanel + * The FormPanel used to retrieve the list of all FormPanelInitializer to retrieve the list of FormPanelInitializerQueryPart + * @param listQueryParametersValue + * The list of all parameter values to used to fill the DAOUtil statement + * @param user + * The current user + * @return the list of all FormPanelInitializerQueryPart associate to all the FormPanelInitializer to retrieve from the given FormPanel + */ + private static List buildFormPanelInitializerQueryPartList( FormPanel formPanel, List listQueryParametersValue, + User user ) + { + List listFormPanelInitializerQueryPart = new ArrayList<>( ); + + IFormPanelConfiguration formPanelConfiguration = formPanel.getFormPanelConfiguration( ); + + if ( formPanelConfiguration != null && !CollectionUtils.isEmpty( formPanel.getListFormPanelInitializer( ) ) ) + { + List listFormPanelInitializer = formPanel.getListFormPanelInitializer( ); + + for ( IFormPanelInitializer formPanelInitializer : listFormPanelInitializer ) + { + IFormPanelInitializerQueryPart formPanelInitializerQueryPart = retrieveFormPanelInitializerQueryPart( formPanelInitializer, + listQueryParametersValue, user ); + if ( formPanelInitializerQueryPart != null ) + { + listFormPanelInitializerQueryPart.add( formPanelInitializerQueryPart ); + } + } + } + return listFormPanelInitializerQueryPart; + } + + /** + * Retrieve the IformPanelInitializerQueryPart associate to the givenFormPanelInitializer + * + * @param formPanelInitializer + * The formPanelInitializer used to retrieve the associated IFormPanelInitializerQueryPart + * @param listQueryParametersPositionValue + * The list of all parameter values to used to fill the DAOUtil statement + * @param user + * The current user + * @return the IFormPanelInitializerQueryPart associate to the given FormPanelInitializer or null if not found + */ + private static IFormPanelInitializerQueryPart retrieveFormPanelInitializerQueryPart( IFormPanelInitializer formPanelInitializer, + List listQueryParametersPositionValue, User user ) + { + IFormPanelInitializerQueryPart formPanelInitializerQueryPartResult = null; + + if ( formPanelInitializer != null ) + { + formPanelInitializerQueryPartResult = formPanelInitializer.getIFormPanelInitializerQueryPart( user ); + + if ( formPanelInitializerQueryPartResult != null ) + { + FormParameters formParameters = formPanelInitializer.getFormParameters( ); + formPanelInitializerQueryPartResult.buildFormPanelInitializerQuery( formParameters ); + + List listUsedParametersValues = formParameters.getListUsedParametersValue( ); + listQueryParametersPositionValue.addAll( listUsedParametersValues ); + } + } + return formPanelInitializerQueryPartResult; + } + /** * Create a FormResponseItem from a DAOUtil * diff --git a/src/java/fr/paris/lutece/plugins/forms/business/form/list/IFormListDAO.java b/src/java/fr/paris/lutece/plugins/forms/business/form/list/IFormListDAO.java index 64aef461a..fd120bea9 100644 --- a/src/java/fr/paris/lutece/plugins/forms/business/form/list/IFormListDAO.java +++ b/src/java/fr/paris/lutece/plugins/forms/business/form/list/IFormListDAO.java @@ -34,6 +34,7 @@ package fr.paris.lutece.plugins.forms.business.form.list; import fr.paris.lutece.plugins.forms.business.form.FormResponseItem; +import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.forms.business.form.FormItemSortConfig; import java.util.List; @@ -65,6 +66,27 @@ public interface IFormListDAO void populateFormColumns( FormPanel formPanel, List listFormColumn, List listFormFilter, int nStartIndex, int nPageSize, FormItemSortConfig sortConfig ); + /** + * Populate the FormPanel with the values returned by the SQL query results + * + * @param formPanel + * The FormPanel used to retrieve the values of the FormColumn + * @param listFormColumn + * The list of FormColumn to populate + * @param listFormFilter + * The list of FormFilter used for filtering the data to retrieve + * @param nStartIndex + * The start index of doc that all will become FormResponseItem + * @param nPageSize + * The number of doc to load for pagination purpose + * @param sortConfig + * The comparator config + * @param user + * The current user + */ + void populateFormColumns( FormPanel formPanel, java.util.List listFormColumn, List listFormFilter, int nStartIndex, int nPageSize, + FormItemSortConfig sortConfig, User user ); + /** * Search the Lucene Index. * diff --git a/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/IFormPanelInitializer.java b/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/IFormPanelInitializer.java index dc8533a69..48d9a92e9 100644 --- a/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/IFormPanelInitializer.java +++ b/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/IFormPanelInitializer.java @@ -33,6 +33,7 @@ */ package fr.paris.lutece.plugins.forms.business.form.panel.initializer; +import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.forms.business.form.FormParameters; import fr.paris.lutece.plugins.forms.business.form.panel.initializer.querypart.IFormPanelInitializerQueryPart; import fr.paris.lutece.plugins.forms.web.form.panel.display.initializer.IFormPanelDisplayInitializer; @@ -64,6 +65,15 @@ public interface IFormPanelInitializer */ IFormPanelInitializerQueryPart getIFormPanelInitializerQueryPart( ); + /** + * Get an {@link IFormPanelInitializerQueryPart} associated with this IFormPanelInitializer. + * + * @param user + * The current user + * @return the IFormPanelInitializerQueryPart Object + */ + IFormPanelInitializerQueryPart getIFormPanelInitializerQueryPart( User user ); + /** * Get an {@link IFormPanelDisplayInitializer} associated with this IFormPanelInitializer. * diff --git a/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormResponseInitializer.java b/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormResponseInitializer.java index 98d851ba0..1bd665f40 100644 --- a/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormResponseInitializer.java +++ b/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormResponseInitializer.java @@ -33,6 +33,7 @@ */ package fr.paris.lutece.plugins.forms.business.form.panel.initializer.impl; +import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.forms.business.form.panel.initializer.querypart.IFormPanelInitializerQueryPart; import fr.paris.lutece.plugins.forms.business.form.panel.initializer.querypart.impl.FormPanelFormResponseInitializerQueryPart; import fr.paris.lutece.plugins.forms.web.form.panel.display.initializer.IFormPanelDisplayInitializer; @@ -54,4 +55,10 @@ public IFormPanelDisplayInitializer getFormPanelDisplayInitializer( ) { return new FormPanelFormResponseDisplayInitializer( ); } + + @Override + public IFormPanelInitializerQueryPart getIFormPanelInitializerQueryPart( User user ) + { + return new FormPanelFormResponseInitializerQueryPart( user ); + } } diff --git a/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormsInitializer.java b/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormsInitializer.java index a2537ce5e..28ff76d50 100644 --- a/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormsInitializer.java +++ b/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormsInitializer.java @@ -33,6 +33,7 @@ */ package fr.paris.lutece.plugins.forms.business.form.panel.initializer.impl; +import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.forms.business.form.panel.initializer.querypart.IFormPanelInitializerQueryPart; import fr.paris.lutece.plugins.forms.business.form.panel.initializer.querypart.impl.FormPanelFormsInitializerQueryPart; import fr.paris.lutece.plugins.forms.web.form.panel.display.initializer.IFormPanelDisplayInitializer; @@ -49,6 +50,12 @@ public IFormPanelInitializerQueryPart getIFormPanelInitializerQueryPart( ) return new FormPanelFormsInitializerQueryPart( ); } + @Override + public IFormPanelInitializerQueryPart getIFormPanelInitializerQueryPart( User user ) + { + return new FormPanelFormsInitializerQueryPart( user ); + } + @Override public IFormPanelDisplayInitializer getFormPanelDisplayInitializer( ) { diff --git a/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/querypart/impl/FormPanelFormResponseInitializerQueryPart.java b/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/querypart/impl/FormPanelFormResponseInitializerQueryPart.java index 53d7d1e21..c36b992d6 100644 --- a/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/querypart/impl/FormPanelFormResponseInitializerQueryPart.java +++ b/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/querypart/impl/FormPanelFormResponseInitializerQueryPart.java @@ -33,6 +33,7 @@ */ package fr.paris.lutece.plugins.forms.business.form.panel.initializer.querypart.impl; +import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.forms.business.form.FormParameters; /** @@ -40,6 +41,16 @@ */ public class FormPanelFormResponseInitializerQueryPart extends AbstractFormPanelInitializerQueryPart { + public FormPanelFormResponseInitializerQueryPart( User user ) + { + super( ); + } + + public FormPanelFormResponseInitializerQueryPart( ) + { + super( ); + } + /** * {@inheritDoc} */ diff --git a/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/querypart/impl/FormPanelFormsInitializerQueryPart.java b/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/querypart/impl/FormPanelFormsInitializerQueryPart.java index 60f5c98bd..0095a2051 100644 --- a/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/querypart/impl/FormPanelFormsInitializerQueryPart.java +++ b/src/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/querypart/impl/FormPanelFormsInitializerQueryPart.java @@ -33,8 +33,24 @@ */ package fr.paris.lutece.plugins.forms.business.form.panel.initializer.querypart.impl; +import fr.paris.lutece.api.user.User; +import fr.paris.lutece.plugins.forms.business.Form; +import fr.paris.lutece.plugins.forms.business.FormHome; import fr.paris.lutece.plugins.forms.business.form.FormParameters; +import fr.paris.lutece.plugins.forms.util.FormsConstants; +import fr.paris.lutece.portal.service.workgroup.AdminWorkgroupService; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.lucene.document.IntPoint; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.BooleanQuery.Builder; import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.search.Query; /** * Implementation of the FormPanelInitializerQueryPart associate to the FormPanelFormsInitializer @@ -50,6 +66,36 @@ public FormPanelFormsInitializerQueryPart( ) setFormPanelInitializerSelectQuery( new MatchAllDocsQuery( ) ); } + /** + * Constructor used to build a query that selects the Forms that the user can access + * + * @param user + * The HTTP user + */ + public FormPanelFormsInitializerQueryPart( User user ) + { + super( ); + + // Get the List of all available Forms + List
listForms = FormHome.getFormList( ); + // Only keep the Forms that can be accessed by the current user + listForms = (List) AdminWorkgroupService.getAuthorizedCollection( listForms, user ); + + // Create Lucene queries to retrieve the Forms that match the specified IDs + List queries = listForms.stream( ).map( form -> IntPoint.newExactQuery( FormsConstants.PARAMETER_ID_FORM, form.getId( ) ) ) + .collect( Collectors.toList( ) ); + + // Create a Lucene Builder for Boolean Queries + Builder builder = new BooleanQuery.Builder( ); + // Add all the created queries that will be applied + queries.forEach( query -> builder.add( query, BooleanClause.Occur.SHOULD ) ); + + // Initialize the Query used to retrieve specific Forms + Query queryForms = builder.build( ); + + setFormPanelInitializerSelectQuery( queryForms ); + } + /** * {@inheritDoc} */ diff --git a/src/java/fr/paris/lutece/plugins/forms/service/FormsMultiviewAuthorizationService.java b/src/java/fr/paris/lutece/plugins/forms/service/FormsMultiviewAuthorizationService.java index 3085ace6f..8fc755e73 100644 --- a/src/java/fr/paris/lutece/plugins/forms/service/FormsMultiviewAuthorizationService.java +++ b/src/java/fr/paris/lutece/plugins/forms/service/FormsMultiviewAuthorizationService.java @@ -34,6 +34,7 @@ package fr.paris.lutece.plugins.forms.service; import fr.paris.lutece.api.user.User; +import fr.paris.lutece.plugins.forms.business.Form; import fr.paris.lutece.plugins.forms.business.form.FormParameters; import java.util.ArrayList; import java.util.List; @@ -56,6 +57,7 @@ import fr.paris.lutece.plugins.forms.util.FormsConstants; import fr.paris.lutece.plugins.forms.web.form.FormDisplayFactory; import fr.paris.lutece.portal.service.admin.AdminUserService; +import fr.paris.lutece.portal.service.workgroup.AdminWorkgroupService; import java.util.HashMap; import java.util.Map; @@ -126,6 +128,22 @@ public boolean isUserAuthorizedOnFormResponse( HttpServletRequest request, int n return bIsUserAuthorizedOnFormResponse; } + /** + * Check if the user is authorized to access the form response within workgroup constraints + * + * @param request + * The request to use to determine if the user can access the details of the given form response + * @param form + * The Form + * @return true if the user is authorized to access the form response, false otherwise + */ + @Override + public boolean isUserAuthorizedOnFormResponseWithinWorkgroup( HttpServletRequest request, Form form ) + { + User user = AdminUserService.getAdminUser( request ); + return AdminWorkgroupService.isAuthorized( form, user ); + } + /** * Build a form response id filter from an id response * diff --git a/src/java/fr/paris/lutece/plugins/forms/service/IFormsMultiviewAuthorizationService.java b/src/java/fr/paris/lutece/plugins/forms/service/IFormsMultiviewAuthorizationService.java index 477c660b6..a94cdecc2 100644 --- a/src/java/fr/paris/lutece/plugins/forms/service/IFormsMultiviewAuthorizationService.java +++ b/src/java/fr/paris/lutece/plugins/forms/service/IFormsMultiviewAuthorizationService.java @@ -35,6 +35,8 @@ import javax.servlet.http.HttpServletRequest; +import fr.paris.lutece.plugins.forms.business.Form; + /** * Forms service for managing the authorization on access form response from the multiview page */ @@ -51,4 +53,16 @@ public interface IFormsMultiviewAuthorizationService * @return the boolean which tell if the connected user is authorized to access the form response or not */ boolean isUserAuthorizedOnFormResponse( HttpServletRequest request, int nIdFormResponse ); + + /** + * Return the boolean which tells if the connected user is authorized to access the form response details or not, depending on their Workgroup and the + * Workgroup of the Form + * + * @param request + * The request to use to determine if the user can access the details of the given Form + * @param form + * The Form whose Workgroup is compared to the user's one + * @return true if the connected user is authorized to access the form response, returns false otherwise + */ + boolean isUserAuthorizedOnFormResponseWithinWorkgroup( HttpServletRequest request, Form form ); } diff --git a/src/java/fr/paris/lutece/plugins/forms/service/MultiviewFormService.java b/src/java/fr/paris/lutece/plugins/forms/service/MultiviewFormService.java index 4be46baf6..fd3d58c9d 100644 --- a/src/java/fr/paris/lutece/plugins/forms/service/MultiviewFormService.java +++ b/src/java/fr/paris/lutece/plugins/forms/service/MultiviewFormService.java @@ -68,6 +68,8 @@ import fr.paris.lutece.plugins.forms.web.form.panel.display.IFormPanelDisplay; import fr.paris.lutece.portal.service.rbac.RBACService; import fr.paris.lutece.portal.service.spring.SpringContextService; +import fr.paris.lutece.portal.service.workgroup.AdminWorkgroupService; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -121,6 +123,31 @@ public void populateFormColumns( FormPanel formPanel, List listForm formListFacade.populateFormColumns( formPanel, listFormColumn, listFormFilter, nStartIndex, nPageSize, sortConfig ); } + /** + * Populate the given FormPanel with the information from the given list of FormColumns and FormFilters + * + * @param formPanel + * The FormPanel used to retrieve the values of the FormColumns + * @param listFormColumn + * The list of all FormColumn to use to be populated + * @param listFormFilter + * The list of FormFilter to use for retrieving the data of the columns to populate + * @param nStartIndex + * The start index of doc to load + * @param nPageSize + * The size of page of docs to load + * @param sortConfig + * The comparator config used for sorting + * @param user + * The current user + */ + public void populateFormColumns( FormPanel formPanel, List listFormColumn, List listFormFilter, int nStartIndex, int nPageSize, + FormItemSortConfig sortConfig, User user ) + { + FormListFacade formListFacade = SpringContextService.getBean( FormListFacade.BEAN_NAME ); + formListFacade.populateFormColumns( formPanel, listFormColumn, listFormFilter, nStartIndex, nPageSize, sortConfig, user ); + } + public List searchAllListFormResponseItem( FormPanel formPanel, List listFormColumn, List listFormFilter, FormItemSortConfig sortConfig ) { @@ -191,13 +218,13 @@ public List getFormColumnsList( Integer nIdForm, Locale locale, Use } } - // Then add global columns from config questions - List listQuestions = ( nIdForm == null || nIdForm == FormsConstants.DEFAULT_ID_VALUE ) ? QuestionHome.getQuestionsListUncomplete( ) - : QuestionHome.getListQuestionByIdFormUncomplete( nIdForm ); + // Get the List of questions the user is authorized to access + List listQuestions = getQuestionListFromAuthorizedForms( nIdForm, user ); // Sort questions by multiview order listQuestions.sort( Comparator.comparing( Question::getMultiviewColumnOrder ) ); + // Then add global columns from config questions addColumnFromConfig( mapFormColumns, listQuestions, true, locale ); if ( nIdForm != null && nIdForm != FormsConstants.DEFAULT_ID_VALUE ) @@ -257,10 +284,10 @@ public List getFormFiltersList( Integer nIdForm, List l } } - // Then add the global question-based for Filters - List listQuestions = ( nIdForm == null || nIdForm == FormsConstants.DEFAULT_ID_VALUE ) ? QuestionHome.getQuestionsListUncomplete( ) - : QuestionHome.getListQuestionByIdFormUncomplete( nIdForm ); + // Get the List of questions the user is authorized to access + List listQuestions = getQuestionListFromAuthorizedForms( nIdForm, user ); + // Then add the global question-based for Filters addFilterFromConfig( mapFormFilter, listQuestions, listFormColumn, true, locale ); if ( nIdForm != null && nIdForm != FormsConstants.DEFAULT_ID_VALUE ) @@ -381,4 +408,43 @@ private void addFilterFromConfig( Map mapFilters, List getQuestionListFromAuthorizedForms( Integer nIdForm, User user ) + { + List listQuestions = new ArrayList<>( ); + + // Retrieve the authorized List of Forms (same workgroups as the User) + List listForms = FormHome.getFormList( ); + listForms = (List) AdminWorkgroupService.getAuthorizedCollection( listForms, user ); + + // If there are multiple Forms to check + if ( nIdForm == null || nIdForm == FormsConstants.DEFAULT_ID_VALUE ) + { + // Retrieve the questions from all the Forms + for ( Form authorizedForm : listForms ) + { + listQuestions.addAll( QuestionHome.getListQuestionByIdFormUncomplete( authorizedForm.getId( ) ) ); + } + } + // If only one Form has to be checked + else + { + // If the given Form is part of the authorized Forms + if ( listForms.stream( ).anyMatch( form -> form.getId( ) == nIdForm ) ) + { + // Retrieve the List of questions from the specified Form + listQuestions = QuestionHome.getListQuestionByIdFormUncomplete( nIdForm ); + } + } + return listQuestions; + } } diff --git a/src/java/fr/paris/lutece/plugins/forms/web/admin/MultiviewFormResponseDetailsJspBean.java b/src/java/fr/paris/lutece/plugins/forms/web/admin/MultiviewFormResponseDetailsJspBean.java index 4f03337be..a65972e0d 100644 --- a/src/java/fr/paris/lutece/plugins/forms/web/admin/MultiviewFormResponseDetailsJspBean.java +++ b/src/java/fr/paris/lutece/plugins/forms/web/admin/MultiviewFormResponseDetailsJspBean.java @@ -179,6 +179,14 @@ public String getResponseDetails( HttpServletRequest request ) throws AccessDeni FormsResourceIdService.PERMISSION_VIEW_FORM_RESPONSE, (User) getUser( ) ); boolean bAuthorizedRecord = _formsMultiviewAuthorizationService.isUserAuthorizedOnFormResponse( request, nIdFormResponse ); + // If the current user is not part of this Form's workgroup then deny them access to the form's responses + if ( bAuthorizedRecord ) + { + int nIdForm = formResponse.getFormId( ); + Form form = FormHome.findByPrimaryKey( nIdForm ); + bAuthorizedRecord = _formsMultiviewAuthorizationService.isUserAuthorizedOnFormResponseWithinWorkgroup( request, form ); + } + if ( !bRBACAuthorization || !bAuthorizedRecord ) { throw new AccessDeniedException( MESSAGE_ACCESS_DENIED ); diff --git a/src/java/fr/paris/lutece/plugins/forms/web/admin/MultiviewFormsJspBean.java b/src/java/fr/paris/lutece/plugins/forms/web/admin/MultiviewFormsJspBean.java index 5d9df6ea5..457ee8ab3 100644 --- a/src/java/fr/paris/lutece/plugins/forms/web/admin/MultiviewFormsJspBean.java +++ b/src/java/fr/paris/lutece/plugins/forms/web/admin/MultiviewFormsJspBean.java @@ -486,6 +486,8 @@ private void buildFormPanelDisplayWithData( HttpServletRequest request, int nInd // Retrieve the list of all FormFilter List listFormFilter = _listFormFilterDisplay.stream( ).map( IFormFilterDisplay::getFormFilter ).collect( Collectors.toList( ) ); + User user = (User) AdminUserService.getAdminUser( request ); + // Check in filters if the columns list has to be fetch again reloadFormColumnList( listFormFilter, request.getLocale( ), (User) AdminUserService.getAdminUser( request ) ); if ( formSelectedAsChanged( request ) ) @@ -501,7 +503,7 @@ private void buildFormPanelDisplayWithData( HttpServletRequest request, int nInd // Populate the FormColumns from the information of the list of FormResponseItem // of the given FormPanel - MultiviewFormService.getInstance( ).populateFormColumns( formPanel, _listFormColumn, listFormFilter, nIndexStart, nPageSize, sortConfig ); + MultiviewFormService.getInstance( ).populateFormColumns( formPanel, _listFormColumn, listFormFilter, nIndexStart, nPageSize, sortConfig, user ); // Associate for each FormColumnDisplay its FormColumnValues if the panel is // active diff --git a/src/java/fr/paris/lutece/plugins/forms/web/form/filter/display/impl/FormFilterDisplayForms.java b/src/java/fr/paris/lutece/plugins/forms/web/form/filter/display/impl/FormFilterDisplayForms.java index 640fa9257..1327f6b6a 100644 --- a/src/java/fr/paris/lutece/plugins/forms/web/form/filter/display/impl/FormFilterDisplayForms.java +++ b/src/java/fr/paris/lutece/plugins/forms/web/form/filter/display/impl/FormFilterDisplayForms.java @@ -54,6 +54,7 @@ import fr.paris.lutece.portal.service.admin.AdminUserService; import fr.paris.lutece.portal.service.rbac.RBACService; import fr.paris.lutece.portal.service.template.AppTemplateService; +import fr.paris.lutece.portal.service.workgroup.AdminWorkgroupService; import fr.paris.lutece.util.ReferenceList; import fr.paris.lutece.util.html.HtmlTemplate; @@ -178,7 +179,11 @@ private ReferenceList createReferenceList( AdminUser user ) List formList = getFormsList( ); formList.removeIf( f -> !RBACService.isAuthorized( Form.RESOURCE_TYPE, String.valueOf( f.getId( ) ), FormsResourceIdService.PERMISSION_VIEW_FORM_RESPONSE, (User) user ) ); - ReferenceListFactory referenceListFactory = new ReferenceListFactory( formList, FORM_CODE_ATTRIBUTE, FORM_NAME_ATTRIBUTE ); + + // Only keep the Forms that are part of the user's Workgroup(s) + List authorizedFormList = (List) AdminWorkgroupService.getAuthorizedCollection( formList, (User) user ); + + ReferenceListFactory referenceListFactory = new ReferenceListFactory( authorizedFormList, FORM_CODE_ATTRIBUTE, FORM_NAME_ATTRIBUTE ); return referenceListFactory.createReferenceList( ); } diff --git a/src/test/java/fr/paris/lutece/plugins/forms/business/form/list/FormListDAOMock.java b/src/test/java/fr/paris/lutece/plugins/forms/business/form/list/FormListDAOMock.java index 11a3a85a2..983c6af79 100644 --- a/src/test/java/fr/paris/lutece/plugins/forms/business/form/list/FormListDAOMock.java +++ b/src/test/java/fr/paris/lutece/plugins/forms/business/form/list/FormListDAOMock.java @@ -37,6 +37,7 @@ import java.util.List; import fr.paris.lutece.plugins.forms.business.form.FormResponseItem; +import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.forms.business.form.FormItemSortConfig; import fr.paris.lutece.plugins.forms.business.form.column.IFormColumn; import fr.paris.lutece.plugins.forms.business.form.filter.FormFilter; @@ -81,6 +82,23 @@ public void populateFormColumns( FormPanel formPanel, List listForm formPanel.setFormResponseItemList( listFormResponseItem ); } + @Override + public void populateFormColumns( FormPanel formPanel, List listFormColumn, List listFormFilter, int nStartIndex, int nPageSize, + FormItemSortConfig sortConfig, User user ) + { + List listFormResponseItem = new ArrayList<>( ); + + for ( Integer nIdFormResponse : _listIdAuthorizedFormResponse ) + { + FormResponseItem formResponseItem = new FormResponseItem( ); + formResponseItem.setIdFormResponse( nIdFormResponse ); + + listFormResponseItem.add( formResponseItem ); + } + + formPanel.setFormResponseItemList( listFormResponseItem ); + } + @Override public List searchAllFormResponseItem( FormPanel formPanel, List listFormColumn, List listFormFilter, FormItemSortConfig sortConfig ) diff --git a/src/test/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormResponseInitializerMock.java b/src/test/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormResponseInitializerMock.java index ada18a1ef..a0a13857a 100644 --- a/src/test/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormResponseInitializerMock.java +++ b/src/test/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormResponseInitializerMock.java @@ -33,6 +33,7 @@ */ package fr.paris.lutece.plugins.forms.business.form.panel.initializer.impl; +import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.forms.business.form.FormParameters; import fr.paris.lutece.plugins.forms.business.form.panel.initializer.IFormPanelInitializer; import fr.paris.lutece.plugins.forms.business.form.panel.initializer.querypart.IFormPanelInitializerQueryPart; @@ -70,6 +71,12 @@ public IFormPanelInitializerQueryPart getIFormPanelInitializerQueryPart( ) return null; } + @Override + public IFormPanelInitializerQueryPart getIFormPanelInitializerQueryPart( User user ) + { + return null; + } + @Override public IFormPanelDisplayInitializer getFormPanelDisplayInitializer( ) { diff --git a/src/test/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormsInitializerMock.java b/src/test/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormsInitializerMock.java index b3ae69649..8634a8261 100644 --- a/src/test/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormsInitializerMock.java +++ b/src/test/java/fr/paris/lutece/plugins/forms/business/form/panel/initializer/impl/FormPanelFormsInitializerMock.java @@ -33,6 +33,7 @@ */ package fr.paris.lutece.plugins.forms.business.form.panel.initializer.impl; +import fr.paris.lutece.api.user.User; import fr.paris.lutece.plugins.forms.business.form.FormParameters; import fr.paris.lutece.plugins.forms.business.form.panel.initializer.IFormPanelInitializer; import fr.paris.lutece.plugins.forms.business.form.panel.initializer.querypart.IFormPanelInitializerQueryPart; @@ -70,6 +71,12 @@ public IFormPanelInitializerQueryPart getIFormPanelInitializerQueryPart( ) return null; } + @Override + public IFormPanelInitializerQueryPart getIFormPanelInitializerQueryPart( User user ) + { + return null; + } + @Override public IFormPanelDisplayInitializer getFormPanelDisplayInitializer( ) {