SecurityHeaderJspBean.java

  1. /*
  2.  * Copyright (c) 2002-2022, City of Paris
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  *  1. Redistributions of source code must retain the above copyright notice
  10.  *     and the following disclaimer.
  11.  *
  12.  *  2. Redistributions in binary form must reproduce the above copyright notice
  13.  *     and the following disclaimer in the documentation and/or other materials
  14.  *     provided with the distribution.
  15.  *
  16.  *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
  17.  *     contributors may be used to endorse or promote products derived from
  18.  *     this software without specific prior written permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
  24.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30.  * POSSIBILITY OF SUCH DAMAGE.
  31.  *
  32.  * License 1.0
  33.  */
  34. package fr.paris.lutece.portal.web.system;

  35. import java.util.HashMap;
  36. import java.util.List;
  37. import java.util.Map;

  38. import javax.servlet.http.HttpServletRequest;

  39. import org.apache.commons.lang3.StringUtils;
  40. import org.apache.commons.text.StringEscapeUtils;

  41. import fr.paris.lutece.portal.business.securityheader.SecurityHeader;
  42. import fr.paris.lutece.portal.business.securityheader.SecurityHeaderHome;
  43. import fr.paris.lutece.portal.business.securityheader.SecurityHeaderType;
  44. import fr.paris.lutece.portal.service.admin.AccessDeniedException;
  45. import fr.paris.lutece.portal.service.message.AdminMessage;
  46. import fr.paris.lutece.portal.service.message.AdminMessageService;
  47. import fr.paris.lutece.portal.service.security.SecurityTokenService;
  48. import fr.paris.lutece.portal.service.securityheader.SecurityHeaderService;
  49. import fr.paris.lutece.portal.service.spring.SpringContextService;
  50. import fr.paris.lutece.portal.service.template.AppTemplateService;
  51. import fr.paris.lutece.portal.service.util.AppLogService;
  52. import fr.paris.lutece.portal.util.mvc.admin.MVCAdminJspBean;
  53. import fr.paris.lutece.util.ErrorMessage;
  54. import fr.paris.lutece.util.ReferenceItem;
  55. import fr.paris.lutece.util.ReferenceList;
  56. import fr.paris.lutece.util.html.HtmlTemplate;
  57. import fr.paris.lutece.util.http.SecurityUtil;

  58. /**
  59.  * This class provides the user interface to manage security headers features ( manage, create, modify, remove, activate/deactivate ).
  60.  */
  61. public class SecurityHeaderJspBean extends MVCAdminJspBean
  62. {
  63.     // Rights
  64.     public static final String RIGHT_SECURITY_HEADER_MANAGEMENT = "CORE_SECURITY_HEADER_MANAGEMENT";

  65.     // Templates
  66.     private static final String TEMPLATE_CREATE_SECURITYHEADER = "admin/system/create_securityheader.html";
  67.     private static final String TEMPLATE_MODIFY_SECURITYHEADER = "admin/system/modify_securityheader.html";
  68.    
  69.     // Markers
  70.     private static final String MARK_SECURITY_HEADERS_LIST = "security_headers_list";
  71.     private static final String MARK_SECURITY_HEADER = "securityheader";
  72.     private static final String MARK_TYPES_LIST = "types_list";
  73.     private static final String MARK_TYPE_SELECTED = "selected_type";
  74.     private static final String MARK_PAGE_CATEGORY_LIST = "page_category_list";
  75.     private static final String MARK_PAGE_CATEGORY_SELECTED = "selected_pageCategory";
  76.     private static final String MARK_ERRORS = "errors";
  77.    
  78.     // Properties
  79.     private static final String PROPERTY_CREATE_SECURITYHEADER_PAGETITLE = "portal.securityheader.create_securityheader.pageTitle";
  80.     private static final String PROPERTY_MODIFY_SECURITYHEADER_PAGETITLE = "portal.securityheader.modify_securityheader.pageTitle";  
  81.     private static final String MESSAGE_ACTIVE_HEADER_NOT_EDITABLE = "portal.securityheader.message.activeHeaderNotEditable";
  82.     private static final String MESSAGE_CONFIRM_REMOVE = "portal.securityheader.message.confirmRemoveSecurityHeader";
  83.     private static final String MESSAGE_HEADER_ALREADY_EXIST = "portal.securityheader.message.securityHeadersAlreadyexists";    
  84.     private static final String MESSAGE_PAGE_CATEGORY_REQUIRED_WHEN_PAGE_IS_TYPE = "portal.securityheader.message.pageCategoryRequiredTypePage";
  85.     private static final String MESSAGE_TYPE_UNKNOWN = "portal.securityheader.message.typeUnknown";
  86.     private static final String MESSAGE_PAGE_CATEGORY_UNKNOWN = "portal.securityheader.message.pageCategoryUnknown";

  87.  // Validations
  88.     private static final String VALIDATION_ATTRIBUTES_PREFIX = "portal.securityheader.model.entity.securityheader.attribute.";
  89.    
  90.     // Template Files path
  91.     private static final String TEMPLATE_MANAGE_SECURITY_HEADERS = "admin/system/manage_security_headers.html";
  92.    
  93.     // Parameters
  94.     private static final String PARAMETER_SECURITY_HEADER_ID = "id_securityheader";
  95.     private static final String PARAMETER_NAME = "name";
  96.     private static final String PARAMETER_VALUE = "value";
  97.     private static final String PARAMETER_DESCRIPTION = "description";
  98.     private static final String PARAMETER_TYPE = "type";
  99.     private static final String PARAMETER_PAGE_CATEGORY  = "pageCategory";
  100.     private static final String PARAMETER_ACTION = "action";
  101.    
  102.     // Jsp definition
  103.     public static final String JSP_MANAGE_SECURITY_HEADERS = "ManageSecurityHeaders.jsp";
  104.     public static final String JSP_REMOVE_SECURITY_HEADERS = "jsp/admin/system/DoRemoveSecurityHeader.jsp";
  105.    
  106.     // Actions
  107.     private static final String ACTION_ENABLE = "ENABLE";
  108.     private static final String ACTION_DISABLE = "DISABLE";
  109.  
  110.     private static final long serialVersionUID = 7010476999488231065L;
  111.    
  112.     /**
  113.      * Returns the page to manage security headers.
  114.      *
  115.      * @param request
  116.      *            The HttpServletRequest
  117.      * @return The HTML code.
  118.      */
  119.     public String getManageSecurityHeaders( HttpServletRequest request )
  120.     {
  121.         HashMap<String, Object> model = createModelForHeadersList( request );
  122.         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MANAGE_SECURITY_HEADERS, getLocale( ), model );

  123.         return getAdminPage( template.getHtml( ) );
  124.     }
  125.    
  126.     /**
  127.      *
  128.      * Creates the model used for displaying security headers list in manage security headers page.
  129.      *
  130.      * @param request
  131.      *            The HttpServletRequest
  132.      * @return model map
  133.      */
  134.     private HashMap<String, Object> createModelForHeadersList( HttpServletRequest request )
  135.     {
  136.         HashMap<String, Object> model = new HashMap<>( );
  137.         model.put( MARK_SECURITY_HEADERS_LIST, getSecurityHeaderService( ).findAllSorted( getLocale( ) ) );
  138.         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MANAGE_SECURITY_HEADERS ) );
  139.        
  140.         return model;
  141.     }
  142.    
  143.     /**
  144.      * Returns the security header creation page.
  145.      *
  146.      * @param request
  147.      *            the http request
  148.      * @return the html code for the securityheader creation page
  149.      */
  150.     public String getCreateSecurityHeader( HttpServletRequest request )
  151.     {
  152.         setPageTitleProperty( PROPERTY_CREATE_SECURITYHEADER_PAGETITLE );
  153.         HashMap<String, Object> model = createModelForHeaderCreation( request );
  154.         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_CREATE_SECURITYHEADER, getLocale( ), model );

  155.         return getAdminPage( template.getHtml( ) );
  156.     }
  157.    
  158.     /**
  159.      *
  160.      * Creates the model used for adding a new security header.
  161.      *
  162.      * @param request
  163.      *            The HttpServletRequest
  164.      * @return model map
  165.      */
  166.     private HashMap<String, Object> createModelForHeaderCreation( HttpServletRequest request )
  167.     {
  168.         ReferenceList listTypes = getSecurityHeaderService( ).getTypeList( );
  169.         ReferenceList listPageCategories = getSecurityHeaderService( ).getPageCategoryList( );
  170.    
  171.         HashMap<String, Object> model = new HashMap<>( );
  172.         model.put( MARK_TYPES_LIST, listTypes );
  173.         model.put( MARK_PAGE_CATEGORY_LIST, listPageCategories );
  174.         if ( !listTypes.isEmpty( ) )
  175.         {
  176.             model.put( MARK_TYPE_SELECTED, listTypes.get( 0 ).getCode( ) );
  177.         }
  178.        
  179.         if ( !listPageCategories.isEmpty( ) )
  180.         {
  181.             model.put( MARK_PAGE_CATEGORY_SELECTED, listPageCategories.get( 0 ).getCode( ) );
  182.         }
  183.         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_CREATE_SECURITYHEADER ) );
  184.        
  185.         return model;
  186.     }
  187.    
  188.     /**
  189.      * Process the data capture form for create a security header
  190.      *
  191.      * @param request
  192.      *            The HTTP Request
  193.      * @return The Jsp URL of the process result
  194.      * @throws AccessDeniedException
  195.      *             If the security token is invalid
  196.      */
  197.     public String doCreateSecurityHeader( HttpServletRequest request ) throws AccessDeniedException
  198.     {
  199.         SecurityHeader securityHeader = new SecurityHeader( );        
  200.         String strErrors = processCreationFormData( request, securityHeader );
  201.        
  202.         if ( strErrors != null )
  203.         {
  204.             return AdminMessageService.getMessageUrl( request, strErrors, AdminMessage.TYPE_STOP );
  205.         }

  206.         if ( !SecurityTokenService.getInstance( ).validate( request, TEMPLATE_CREATE_SECURITYHEADER ) )
  207.         {
  208.             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
  209.         }
  210.        
  211.         getSecurityHeaderService( ).create( securityHeader );

  212.         return JSP_MANAGE_SECURITY_HEADERS;
  213.     }
  214.    
  215.     /**
  216.      * Process Creation Form Data.
  217.      *
  218.      * @param request
  219.      *            The HTTP request
  220.      * @param securityheader
  221.      *            The security header
  222.      * @return An Error message or null if no error
  223.      */
  224.     private String processCreationFormData( HttpServletRequest request, SecurityHeader securityHeader )
  225.     {
  226.         securityHeader.setName( request.getParameter( PARAMETER_NAME ) );
  227.         securityHeader.setValue( request.getParameter( PARAMETER_VALUE ) );
  228.         securityHeader.setDescription( request.getParameter( PARAMETER_DESCRIPTION ) );
  229.         securityHeader.setType( request.getParameter( PARAMETER_TYPE ) );
  230.         securityHeader.setPageCategory( getPageCategory( request.getParameter( PARAMETER_PAGE_CATEGORY ), securityHeader.getType( ) ) );
  231.        
  232.         String strErrors = processCommonControls( securityHeader );
  233.         if( strErrors != null )
  234.         {
  235.             return strErrors;
  236.         }

  237.         if( !isSecurityHeaderToCreateUnique( securityHeader ) )
  238.         {
  239.             return MESSAGE_HEADER_ALREADY_EXIST;
  240.         }
  241.        
  242.         return null;
  243.     }
  244.    
  245.    
  246.     /**
  247.      * Executes common controls between creation and modification actions on request parameters
  248.      *
  249.      * @param securityHeader
  250.      *           Security header to control
  251.      * @return null if controls are passed, an string containing an error message otherwise
  252.      */
  253.     private String processCommonControls( SecurityHeader securityHeader )
  254.     {
  255.        
  256.         if( !validateBean( securityHeader, VALIDATION_ATTRIBUTES_PREFIX ) )
  257.         {
  258.             List<ErrorMessage> listErrors = ( List<ErrorMessage> ) getModel( ).get( MARK_ERRORS );
  259.             return listErrors.get( 0 ).getMessage( );
  260.         }

  261.         if( !isTypeBelongsToReferenceList ( securityHeader.getType( ) ) )
  262.         {
  263.             return MESSAGE_TYPE_UNKNOWN;
  264.         }
  265.        
  266.         if( securityHeader.getPageCategory( ) != null && !isPageCategoryBelongsToReferenceList ( securityHeader.getPageCategory( ) ) )
  267.         {
  268.             return MESSAGE_PAGE_CATEGORY_UNKNOWN;
  269.         }
  270.        
  271.         if( SecurityHeaderType.PAGE.getCode( ).equals( securityHeader.getType( ) ) && StringUtils.isEmpty( securityHeader.getPageCategory( ) ) )
  272.         {
  273.             return MESSAGE_PAGE_CATEGORY_REQUIRED_WHEN_PAGE_IS_TYPE;
  274.         }
  275.        
  276.         return null;
  277.     }
  278.    
  279.     /**
  280.      * Checks if specified type is found in the reference list of security headers types
  281.      *
  282.      * @param strType
  283.      *         THe security header type
  284.      * @return true if type belongs to the reference types list, false otherwise
  285.      */
  286.     private boolean isTypeBelongsToReferenceList( String strType )
  287.     {
  288.         for (ReferenceItem referenceType : getSecurityHeaderService( ).getTypeList( ) )
  289.         {
  290.             if ( strType.equals( referenceType.getCode() ) )
  291.             {
  292.                 return true;
  293.             }
  294.         }
  295.        
  296.         return false;
  297.     }
  298.    
  299.     /**
  300.      * Checks if specified page category is found in the reference list of security headers page categories
  301.      *
  302.      * @param strPageCategory
  303.      *         The security header page category
  304.      * @return true if page category belongs to the reference types list, false otherwise
  305.      */
  306.     private boolean isPageCategoryBelongsToReferenceList( String strPageCategory )
  307.     {
  308.         for (ReferenceItem referencePageCategory : getSecurityHeaderService( ).getPageCategoryList( ) )
  309.         {
  310.             if ( strPageCategory.equals( referencePageCategory.getCode() ) )
  311.             {
  312.                 return true;
  313.             }
  314.         }
  315.        
  316.         return false;
  317.     }
  318.    
  319.     /**
  320.      * Checks if the security header to create doesn't already exist to prevent duplicates.
  321.      * The criteria used to determine if a security header is unique are name, type and page category (in case of security header type is equals to page).
  322.      *
  323.      * @param securityHeaderToCreate
  324.      *            The security header to create
  325.      * @return true if the security header doesn't exist, false otherwise
  326.      */
  327.     private boolean isSecurityHeaderToCreateUnique( SecurityHeader securityHeaderToCreate )
  328.     {  
  329.         return getSecurityHeaderService( ).find( securityHeaderToCreate.getName( ), securityHeaderToCreate.getType( ) , securityHeaderToCreate.getPageCategory( ) ).isEmpty( );
  330.     }
  331.    
  332.     /**
  333.      * Returns the security header modification page.
  334.      *
  335.      * @param request
  336.      *            the http request
  337.      * @return the html code for the securityheader modification page
  338.      */
  339.     public String getModifySecurityHeader( HttpServletRequest request )
  340.     {
  341.         setPageTitleProperty( PROPERTY_MODIFY_SECURITYHEADER_PAGETITLE );

  342.         String strSecurityHeaderId = request.getParameter( PARAMETER_SECURITY_HEADER_ID );

  343.         if ( !StringUtils.isNumeric( strSecurityHeaderId ) )
  344.         {
  345.             AppLogService.error( " {} is not a valid security header id.", ( ) -> SecurityUtil.logForgingProtect( strSecurityHeaderId ) );

  346.             return getManageSecurityHeaders( request );
  347.         }
  348.        
  349.         SecurityHeader securityHeader = getSecurityHeaderForModification( strSecurityHeaderId );
  350.         if ( securityHeader == null )
  351.         {
  352.             AppLogService.error( "{} is not a valid security header id.", ( ) -> SecurityUtil.logForgingProtect( strSecurityHeaderId ) );

  353.             return getManageSecurityHeaders( request );
  354.         }

  355.         HashMap<String, Object> model = createModelForHeaderModification( request, securityHeader );
  356.         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MODIFY_SECURITYHEADER, getLocale( ), model );

  357.         return getAdminPage( template.getHtml( ) );
  358.     }

  359.     /**
  360.      * This method returns the security header to modify. Value field is escaped because some headers values can have double quotes
  361.      * (Clear-site-data header for instance) and in this case, the value is not displayed on the modification screen
  362.      *
  363.      * @param strSecurityHeaderId
  364.      *          The security header id
  365.      * @return security header to modify
  366.      */
  367.     private SecurityHeader getSecurityHeaderForModification( String strSecurityHeaderId )
  368.     {
  369.         SecurityHeader securityHeader = SecurityHeaderHome.findByPrimaryKey( Integer.parseInt( strSecurityHeaderId ) );
  370.         if( securityHeader != null )
  371.         {
  372.             securityHeader.setValue( StringEscapeUtils.escapeHtml4( securityHeader.getValue( ) ) );
  373.         }
  374.        
  375.         return securityHeader;
  376.     }
  377.    
  378.     /**
  379.      * Returns the message page that informs that a security header is not editable.
  380.      *
  381.      * @param request
  382.      *            The Http Request
  383.      * @return the confirmation url
  384.      */
  385.     public String getMessageNotEditableSecurityHeader( HttpServletRequest request )
  386.     {    
  387.         return AdminMessageService.getMessageUrl( request, MESSAGE_ACTIVE_HEADER_NOT_EDITABLE, AdminMessage.TYPE_INFO );
  388.     }
  389.      
  390.     /**
  391.      *
  392.      * Creates the model used for modifying a security header.
  393.      *
  394.      * @param request
  395.      *            The HttpServletRequest
  396.      * @return model map
  397.      */
  398.     private HashMap<String, Object> createModelForHeaderModification(HttpServletRequest request, SecurityHeader securityHeader)
  399.     {
  400.         ReferenceList listTypes = getSecurityHeaderService().getTypeList( );
  401.         ReferenceList listPageCategories = getSecurityHeaderService().getPageCategoryList( );

  402.         HashMap<String, Object> model = new HashMap<>( );
  403.         model.put( MARK_TYPES_LIST, listTypes );
  404.         model.put( MARK_PAGE_CATEGORY_LIST, listPageCategories );        
  405.         model.put( MARK_TYPE_SELECTED, securityHeader.getType() );
  406.         String selectedCategory = null;
  407.         if(securityHeader.getType().equals(SecurityHeaderType.PAGE.getCode()))
  408.         {
  409.             selectedCategory = securityHeader.getPageCategory();
  410.         }
  411.         else
  412.         {
  413.             selectedCategory = listPageCategories.get( 0 ).getCode( );
  414.         }
  415.         model.put( MARK_PAGE_CATEGORY_SELECTED, selectedCategory );
  416.         model.put( MARK_SECURITY_HEADER, securityHeader );
  417.         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MODIFY_SECURITYHEADER ) );
  418.         return model;
  419.     }
  420.    
  421.     /**
  422.      * Processes the data capture form for modifying a security header.
  423.      *
  424.      * @param request
  425.      *            The HTTP Request
  426.      * @return The Jsp URL of the process result
  427.      * @throws AccessDeniedException
  428.      *             if the security token is invalid
  429.      */
  430.     public String doModifySecurityHeader( HttpServletRequest request ) throws AccessDeniedException
  431.     {
  432.         int nId = Integer.parseInt( request.getParameter( PARAMETER_SECURITY_HEADER_ID ) );
  433.         SecurityHeader securityHeader = SecurityHeaderHome.findByPrimaryKey( nId );

  434.         String strErrors = processModifyFormData( request, securityHeader );

  435.         if ( strErrors != null )
  436.         {
  437.             return AdminMessageService.getMessageUrl( request, strErrors, AdminMessage.TYPE_STOP );
  438.         }
  439.         if ( !SecurityTokenService.getInstance( ).validate( request, TEMPLATE_MODIFY_SECURITYHEADER ) )
  440.         {
  441.             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
  442.         }

  443.         getSecurityHeaderService( ).update( securityHeader );

  444.         return getHomeUrl( request );
  445.     }
  446.    
  447.     /**
  448.      * Processes Modify Form Data.
  449.      *
  450.      * @param request
  451.      *            The HTTP request
  452.      * @param securityheader
  453.      *            The security header
  454.      * @return An Error message or null if no error
  455.      */
  456.     private String processModifyFormData( HttpServletRequest request, SecurityHeader securityHeader )
  457.     {
  458.         securityHeader.setName( request.getParameter( PARAMETER_NAME ) );
  459.         securityHeader.setValue( request.getParameter( PARAMETER_VALUE ) );
  460.         securityHeader.setDescription( request.getParameter( PARAMETER_DESCRIPTION ) );
  461.         securityHeader.setType( request.getParameter( PARAMETER_TYPE ) );
  462.         securityHeader.setPageCategory( getPageCategory( request.getParameter( PARAMETER_PAGE_CATEGORY ), securityHeader.getType( ) ) );
  463.        
  464.         String strErrors = processCommonControls( securityHeader );
  465.         if( strErrors != null )
  466.         {
  467.             return strErrors;
  468.         }
  469.        
  470.         if( !isSecurityHeaderToModifyUnique( securityHeader, securityHeader.getName( ), securityHeader.getType( ), securityHeader.getPageCategory( )  ) )
  471.         {
  472.             return MESSAGE_HEADER_ALREADY_EXIST;
  473.         }
  474.        
  475.         return null;
  476.     }
  477.    
  478.     /**
  479.      * Returns security header page category from request if security header type is page.
  480.      * If type is REST api, page category is not relevant and should not be filled so the method returns null.
  481.      *
  482.      * @param strType
  483.      * @param strPageCategoryFromRequest
  484.      * @return
  485.      */
  486.     private String getPageCategory( String strPageCategoryFromRequest, String strType )
  487.     {  
  488.         if( SecurityHeaderType.PAGE.getCode( ).equals( strType ) )
  489.         {
  490.             return strPageCategoryFromRequest ;
  491.         }
  492.        
  493.         return null;
  494.     }
  495.    
  496.     /**
  497.      * Checks if the security header to modify will be always unique after modifications are applied to prevent duplicates.
  498.      * The criteria used to determine if a security header is unique are name, type and page category (in case of security header type is equals to page).
  499.      *
  500.      * @param securityHeaderToModify
  501.      *            The security header to modify
  502.      * @param strName
  503.      *            The name to set  
  504.      * @param strType
  505.      *            The type to set
  506.      * @param strPageCategory
  507.      *            The page category to set
  508.      * @return true if the security header after modification will be still unique, false otherwise
  509.      */
  510.     private boolean isSecurityHeaderToModifyUnique( SecurityHeader securityHeaderToModify, String strName, String strType, String strPageCategory )
  511.     {  
  512.         for( SecurityHeader securityHeader : getSecurityHeaderService( ).find( strName, strType, strPageCategory ) )
  513.         {
  514.             if( securityHeaderToModify.getId( ) != securityHeader.getId( ) )
  515.             {
  516.                 return false;
  517.             }              
  518.         }
  519.        
  520.         return true;
  521.     }
  522.    
  523.     /**
  524.      * Returns the page of confirmation for deleting a security header.
  525.      *
  526.      * @param request
  527.      *            The Http Request
  528.      * @return the confirmation url
  529.      */
  530.     public String getConfirmRemoveSecurityHeader( HttpServletRequest request )
  531.     {  
  532.         Map<String, String> parameters = new HashMap<>( );
  533.         parameters.put( PARAMETER_SECURITY_HEADER_ID, request.getParameter( PARAMETER_SECURITY_HEADER_ID ) );
  534.         parameters.put( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, JSP_REMOVE_SECURITY_HEADERS ) );
  535.        
  536.         return AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE, JSP_REMOVE_SECURITY_HEADERS, AdminMessage.TYPE_CONFIRMATION, parameters );
  537.     }
  538.    
  539.     /**
  540.      * Processes the data capture form for removing a security header.
  541.      *
  542.      * @param request
  543.      *            The HTTP Request
  544.      * @return The Jsp URL of the process result
  545.      * @throws AccessDeniedException
  546.      *             if the security token is invalid
  547.      */
  548.     public String doRemoveSecurityHeader( HttpServletRequest request ) throws AccessDeniedException
  549.     {
  550.         if ( !SecurityTokenService.getInstance( ).validate( request, JSP_REMOVE_SECURITY_HEADERS ) )
  551.         {
  552.             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
  553.         }
  554.         String strId = request.getParameter( PARAMETER_SECURITY_HEADER_ID );
  555.         getSecurityHeaderService( ).remove( Integer.parseInt( strId ) );
  556.        
  557.         return JSP_MANAGE_SECURITY_HEADERS;
  558.     }
  559.    
  560.     /**
  561.      * Processes the security headers actions (enable and disable).
  562.      *
  563.      * @param request
  564.      *            The HTTP request
  565.      * @return The forward URL
  566.      * @throws AccessDeniedException
  567.      *             if the security token is invalid
  568.      */
  569.     public String doSecurityHeaderAction( HttpServletRequest request ) throws AccessDeniedException
  570.     {
  571.         String strAction = request.getParameter( PARAMETER_ACTION );
  572.         int nId = Integer.parseInt( request.getParameter( PARAMETER_SECURITY_HEADER_ID ) );
  573.        
  574.         if ( !SecurityTokenService.getInstance( ).validate( request, TEMPLATE_MANAGE_SECURITY_HEADERS ) )
  575.         {
  576.             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
  577.         }
  578.         switch( strAction )
  579.         {
  580.             case ACTION_ENABLE:
  581.                 getSecurityHeaderService( ).enable( nId );
  582.                 break;
  583.             case ACTION_DISABLE:
  584.                 getSecurityHeaderService( ).disable( nId );
  585.                 break;
  586.             default:
  587.                 AppLogService.error( "Unknown security header action : {}", strAction );
  588.         }

  589.         return getHomeUrl( request );
  590.     }
  591.    
  592.     /**
  593.      * Returns the security header service.
  594.      *
  595.      * @return the security header service
  596.      */
  597.     private SecurityHeaderService getSecurityHeaderService( )
  598.     {
  599.         return SpringContextService.getBean( "securityHeaderService" );
  600.     }
  601. }