RBACService.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.service.rbac;

  35. import fr.paris.lutece.api.user.User;
  36. import fr.paris.lutece.api.user.UserRole;
  37. import fr.paris.lutece.portal.business.rbac.RBAC;
  38. import fr.paris.lutece.portal.business.rbac.RBACHome;
  39. import fr.paris.lutece.portal.business.user.AdminUser;
  40. import fr.paris.lutece.util.ReferenceItem;
  41. import fr.paris.lutece.util.ReferenceList;

  42. import java.util.ArrayList;
  43. import java.util.Collection;
  44. import java.util.Collections;
  45. import java.util.HashMap;
  46. import java.util.Map;
  47. import java.util.Set;
  48. import java.util.stream.Collectors;

  49. /**
  50.  * This class provides the main methods to control the access to a resource depending on the user's roles
  51.  */
  52. public final class RBACService
  53. {

  54.     /**
  55.      * ReferenceItem as an RBACResource
  56.      */
  57.     private static final class RBACReferenceItem implements RBACResource
  58.     {
  59.         private final String _strResourceType;
  60.         private final ReferenceItem _item;

  61.         /**
  62.          * Constructor
  63.          *
  64.          * @param strResourceType
  65.          *            the resource type
  66.          * @param item
  67.          *            the reference item
  68.          */
  69.         public RBACReferenceItem( String strResourceType, ReferenceItem item )
  70.         {
  71.             _strResourceType = strResourceType;
  72.             _item = item;
  73.         }

  74.         @Override
  75.         public String getResourceTypeCode( )
  76.         {
  77.             return _strResourceType;
  78.         }

  79.         @Override
  80.         public String getResourceId( )
  81.         {
  82.             return _item.getCode( );
  83.         }

  84.         /**
  85.          * The reference item
  86.          *
  87.          * @return the reference item
  88.          */
  89.         public ReferenceItem getItem( )
  90.         {
  91.             return _item;
  92.         }

  93.     }

  94.     /**
  95.      * Constructor
  96.      */
  97.     private RBACService( )
  98.     {
  99.     }

  100.     /**
  101.      * Check that a given user is allowed to access a resource for a given permission
  102.      *
  103.      * @param strResourceTypeCode
  104.      *            the key of the resource type being considered
  105.      * @param strResourceId
  106.      *            the id of the resource being considered
  107.      * @param strPermission
  108.      *            the permission needed
  109.      * @param user
  110.      *            the user trying to access the ressource
  111.      * @return true if the user can access the given resource with the given permission, false otherwise
  112.      */
  113.     public static boolean isAuthorized( String strResourceTypeCode, String strResourceId, String strPermission, User user )
  114.     {
  115.         // Check user roles
  116.         Collection<String> colRoles = RBACHome.findRoleKeys( strResourceTypeCode, strResourceId, strPermission );

  117.         for ( String strRole : colRoles )
  118.         {
  119.             if ( isUserInRole( user, strRole ) )
  120.             {
  121.                 return true;
  122.             }
  123.         }

  124.         return false;
  125.     }

  126.     /**
  127.      * Check that a given user is allowed to access a resource for a given permission
  128.      *
  129.      * @param strResourceTypeCode
  130.      *            the key of the resource type being considered
  131.      * @param strResourceId
  132.      *            the id of the resource being considered
  133.      * @param strPermission
  134.      *            the permission needed
  135.      * @param user
  136.      *            the user trying to access the ressource
  137.      * @return true if the user can access the given resource with the given permission, false otherwise
  138.      * @deprecated use isAuthorized( String, String, String, User )
  139.      */
  140.     @Deprecated
  141.     public static boolean isAuthorized( String strResourceTypeCode, String strResourceId, String strPermission, AdminUser user )
  142.     {
  143.         return isAuthorized( strResourceTypeCode, strResourceId, strPermission, (User) user );
  144.     }

  145.     /**
  146.      * Check that a given user is allowed to access a resource for a given permission
  147.      *
  148.      * @param resource
  149.      *            the resource object being considered
  150.      * @param strPermission
  151.      *            the permission needed
  152.      * @param user
  153.      *            the user trying to access the ressource
  154.      * @return true if the user can access the given resource with the given permission, false otherwise
  155.      */
  156.     public static boolean isAuthorized( RBACResource resource, String strPermission, User user )
  157.     {
  158.         boolean bAuthorized = false;

  159.         if ( resource != null )
  160.         {
  161.             bAuthorized = isAuthorized( resource.getResourceTypeCode( ), resource.getResourceId( ), strPermission, user );
  162.         }

  163.         return bAuthorized;
  164.     }

  165.     /**
  166.      * Check that a given user is allowed to access a resource for a given permission
  167.      *
  168.      * @param resource
  169.      *            the resource object being considered
  170.      * @param strPermission
  171.      *            the permission needed
  172.      * @param user
  173.      *            the user trying to access the ressource
  174.      * @return true if the user can access the given resource with the given permission, false otherwise
  175.      * @deprecated use isAuthorized( RBACResource, String, User )
  176.      */
  177.     @Deprecated
  178.     public static boolean isAuthorized( RBACResource resource, String strPermission, AdminUser user )
  179.     {
  180.         return isAuthorized( resource, strPermission, (User) user );
  181.     }

  182.     /**
  183.      * Check that a given user is in the given role
  184.      *
  185.      * @param user
  186.      *            The user
  187.      * @param strRole
  188.      *            The role
  189.      * @return true if the user has the given role, false otherwise
  190.      */
  191.     public static boolean isUserInRole( User user, String strRole )
  192.     {
  193.         Map<String, UserRole> userRoles = user.getUserRoles( );

  194.         return userRoles.containsKey( strRole );
  195.     }

  196.     /**
  197.      * Check that a given user is in the given role
  198.      *
  199.      * @param user
  200.      *            The user
  201.      * @param strRole
  202.      *            The role
  203.      * @return true if the user has the given role, false otherwise
  204.      * @deprecated use isUserInRole( User, String )
  205.      */
  206.     @Deprecated
  207.     public static boolean isUserInRole( AdminUser user, String strRole )
  208.     {
  209.         return isUserInRole( (User) user, strRole );
  210.     }

  211.     /**
  212.      * Filter a collection of resources for a given user
  213.      *
  214.      * @param <E>
  215.      *            The RBAC resource
  216.      * @param collection
  217.      *            The collection to filter
  218.      * @param strPermission
  219.      *            Permission to check
  220.      * @param user
  221.      *            The user
  222.      * @return A filtered collection of resources
  223.      */
  224.     public static <E extends RBACResource> Collection<E> getAuthorizedCollection( Collection<E> collection, String strPermission, User user )
  225.     {
  226.         if ( user == null )
  227.         {
  228.             return Collections.emptyList( );
  229.         }
  230.         Map<String, Collection<RBAC>> rbacsByResourceType = new HashMap<>( );
  231.         RBACHome.findByPermissionAndRoles( strPermission, user.getUserRoles( ).keySet( ) ).stream( ).forEach( rbac -> {
  232.             rbacsByResourceType.computeIfAbsent( rbac.getResourceTypeKey( ), t -> new ArrayList<>( ) ).add( rbac );
  233.         } );
  234.         return collection.stream( )
  235.                 .filter( resource -> rbacsByResourceType
  236.                         .getOrDefault( resource.getResourceTypeCode( ), Collections.emptyList( ) ).stream( )
  237.                         .anyMatch( rbac -> RBAC.WILDCARD_RESOURCES_ID.equals( rbac.getResourceId( ) )
  238.                                 || resource.getResourceId( ).equals( rbac.getResourceId( ) ) ) )
  239.                 .collect( Collectors.toList( ) );
  240.     }

  241.     /**
  242.      * Filter a collection of resources for a given user
  243.      *
  244.      * @param <E>
  245.      *            The RBAC resource
  246.      * @param collection
  247.      *            The collection to filter
  248.      * @param strPermission
  249.      *            Permission to check
  250.      * @param user
  251.      *            The user
  252.      * @return A filtered collection of resources
  253.      * @deprecated use getAuthorizedCollection( Collection, String, User )
  254.      */
  255.     @Deprecated
  256.     public static <E extends RBACResource> Collection<E> getAuthorizedCollection( Collection<E> collection, String strPermission, AdminUser user )
  257.     {
  258.         return getAuthorizedCollection( collection, strPermission, (User) user );
  259.     }

  260.     /**
  261.      * Filter a Reference List for a given user
  262.      *
  263.      * @param listResources
  264.      *            The list to filter
  265.      * @param strResourceType
  266.      *            The resource type
  267.      * @param strPermission
  268.      *            The permission to check
  269.      * @param user
  270.      *            The user
  271.      * @return The filtered collection
  272.      */
  273.     public static ReferenceList getAuthorizedReferenceList( ReferenceList listResources, String strResourceType, String strPermission, User user )
  274.     {
  275.         return getAuthorizedCollection( listResources.stream( )
  276.                 .map( item -> new RBACReferenceItem( strResourceType, item ) ).collect( Collectors.toList( ) ),
  277.                 strPermission, user ).stream( ).map( RBACReferenceItem::getItem )
  278.                         .collect( Collectors.toCollection( ReferenceList::new ) );
  279.     }

  280.     /**
  281.      * Filter a Reference List for a given user
  282.      *
  283.      * @param listResources
  284.      *            The list to filter
  285.      * @param strResourceType
  286.      *            The resource type
  287.      * @param strPermission
  288.      *            The permission to check
  289.      * @param user
  290.      *            The user
  291.      * @return The filtered collection
  292.      * @deprecated use getAuthorizedReferenceList( ReferenceList, String, String, User )
  293.      */
  294.     @Deprecated
  295.     public static ReferenceList getAuthorizedReferenceList( ReferenceList listResources, String strResourceType, String strPermission, AdminUser user )
  296.     {
  297.         return getAuthorizedReferenceList( listResources, strResourceType, strPermission, (User) user );
  298.     }

  299.     /**
  300.      * Filter a collection of RBACAction for a given user
  301.      *
  302.      * @param <E>
  303.      *            The RBAC resource
  304.      * @param collection
  305.      *            The collection to filter
  306.      * @param resource
  307.      *            The resource
  308.      * @param user
  309.      *            The user
  310.      * @return The filtered collection
  311.      */
  312.     public static <E extends RBACAction> Collection<E> getAuthorizedActionsCollection( Collection<E> collection, RBACResource resource, User user )
  313.     {
  314.         if ( collection.isEmpty( ) )
  315.         {
  316.             return collection;
  317.         }
  318.         Set<String> permissions = RBACHome
  319.                 .findByPermissionsAndRoles(
  320.                         collection.stream( ).map( RBACAction::getPermission ).collect( Collectors.toSet( ) ),
  321.                         user.getUserRoles( ).keySet( ) )
  322.                 .stream( ).filter( rbac -> resource.getResourceTypeCode( ).equals( rbac.getResourceTypeKey( ) ) )
  323.                 .filter( rbac -> RBAC.WILDCARD_RESOURCES_ID.equals( rbac.getResourceId( ) )
  324.                         || resource.getResourceId( ).equals( rbac.getResourceId( ) ) )
  325.                 .map( RBAC::getPermissionKey ).collect( Collectors.toSet( ) );
  326.         return collection.stream( ).filter( action -> permissions.contains( action.getPermission( ) )
  327.                 || permissions.contains( RBAC.WILDCARD_PERMISSIONS_KEY ) ).collect( Collectors.toList( ) );
  328.     }

  329.     /**
  330.      * Filter a collection of RBACAction for a given user
  331.      *
  332.      * @param <E>
  333.      *            The RBAC resource
  334.      * @param collection
  335.      *            The collection to filter
  336.      * @param resource
  337.      *            The resource
  338.      * @param user
  339.      *            The user
  340.      * @return The filtered collection
  341.      * @deprecated use getAuthorizedActionsCollection( Collection, RBACResource, User )
  342.      */
  343.     @Deprecated
  344.     public static <E extends RBACAction> Collection<E> getAuthorizedActionsCollection( Collection<E> collection, RBACResource resource, AdminUser user )
  345.     {
  346.         return getAuthorizedActionsCollection( collection, resource, (User) user );
  347.     }

  348. }