UnitUserService.java
/*
* Copyright (c) 2002-2021, City of Paris
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright notice
* and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice
* and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* License 1.0
*/
package fr.paris.lutece.plugins.unittree.service.unit;
import fr.paris.lutece.plugins.unittree.business.unit.Unit;
import fr.paris.lutece.plugins.unittree.business.unit.UnitHome;
import fr.paris.lutece.portal.business.user.AdminUser;
import fr.paris.lutece.portal.business.user.AdminUserHome;
import fr.paris.lutece.portal.business.workgroup.AdminWorkgroupHome;
import fr.paris.lutece.portal.service.util.AppPropertiesService;
import fr.paris.lutece.util.ReferenceItem;
import fr.paris.lutece.util.ReferenceList;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
/**
*
* UnitUserService
*
*/
public class UnitUserService implements IUnitUserService
{
private static final String PROPERTY_MULTI_AFFECTATION_ENABLED = "unittree.users.enableMultiAffectation";
private static final boolean DEFAULT_MULTI_AFFECTATION_ENABLED = false;
@Inject
private IUnitService _unitService;
// GET
/**
* {@inheritDoc}
*/
@Override
public AdminUser getUser( int nIdUser )
{
return AdminUserHome.findByPrimaryKey( nIdUser );
}
/**
* {@inheritDoc}
*/
@Override
public List<AdminUser> getUsers( int nIdUnit, Map<String, Unit> mapIdUserUnit, boolean isInDepthSearch )
{
List<AdminUser> listAdminUsers = new ArrayList<>( );
// First add the users from the current unit
listAdminUsers.addAll( getUsers( nIdUnit, mapIdUserUnit ) );
if ( isInDepthSearch )
{
// Then add the users from the sub units
for ( Unit subUnit : _unitService.getSubUnits( nIdUnit, false ) )
{
// Recursive function in order to get all users from all sub units of the unit
listAdminUsers.addAll( getUsers( subUnit.getIdUnit( ), mapIdUserUnit, isInDepthSearch ) );
}
}
return listAdminUsers;
}
/**
* {@inheritDoc}
*/
@Override
public List<AdminUser> getAvailableUsers( AdminUser currentUser, int nIdUnit, boolean bMultiAffectationEnabled )
{
List<AdminUser> listUsers = new ArrayList<>( );
Unit unit = _unitService.getUnit( nIdUnit, false );
for ( AdminUser user : AdminUserHome.findUserList( ) )
{
if ( isUserAvailable( currentUser, user, unit, bMultiAffectationEnabled ) )
{
listUsers.add( user );
}
}
return listUsers;
}
/**
* {@inheritDoc}
*/
@Override
public List<AdminUser> getAvailableUsers( AdminUser currentUser, int nIdUnit )
{
boolean bMultiAffectationEnabled = isMultiAffectationEnabled( );
return getAvailableUsers( currentUser, nIdUnit, bMultiAffectationEnabled );
}
// PROCESS
/**
* {@inheritDoc}
*/
@Override
public void doProcessAddUser( int nIdUser, AdminUser currentUser, HttpServletRequest request )
{
for ( IUnitUserAttributeService service : UnitUserAttributeManager.getListUnitUserAttributeService( ) )
{
service.doAddUser( nIdUser, currentUser, request );
}
}
/**
* {@inheritDoc}
*/
@Override
public void doProcessModifyUser( int nIdUser, AdminUser currentUser, HttpServletRequest request )
{
for ( IUnitUserAttributeService service : UnitUserAttributeManager.getListUnitUserAttributeService( ) )
{
service.doModifyUser( nIdUser, currentUser, request );
}
}
/**
* {@inheritDoc}
*/
@Override
public void doProcessRemoveUser( int nIdUser, AdminUser currentUser, HttpServletRequest request )
{
for ( IUnitUserAttributeService service : UnitUserAttributeManager.getListUnitUserAttributeService( ) )
{
service.doRemoveUser( nIdUser, currentUser, request );
}
}
// CHECKS
/**
* {@inheritDoc}
*/
@Override
public boolean isUserInUnit( int nIdUser, int nIdUnit )
{
return UnitHome.isUserInUnit( nIdUser, nIdUnit );
}
// CRUD
/**
* {@inheritDoc}
*/
@Override
@Transactional( "unittree.transactionManager" )
public boolean addUserToUnit( int nIdUnit, int nIdUser )
{
if ( !isUserInUnit( nIdUser, nIdUnit ) )
{
Unit unit = UnitHome.findByPrimaryKey( nIdUnit );
List<Unit> listUnits = _unitService.getUnitsByIdUser( nIdUser, false );
boolean bMultiAffectationEnabled = isMultiAffectationEnabled( );
if ( !bMultiAffectationEnabled && CollectionUtils.isNotEmpty( listUnits ) )
{
return false;
}
for ( Unit userUnit : listUnits )
{
if ( _unitService.isParent( unit, userUnit ) )
{
removeUserFromUnit( nIdUser, userUnit.getIdUnit( ) );
}
}
UnitHome.addUserToUnit( nIdUnit, nIdUser );
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
@Transactional( "unittree.transactionManager" )
public void removeUserFromUnit( int nIdUser, int nIdUnit )
{
UnitHome.removeUserFromUnit( nIdUser, nIdUnit );
}
/**
* {@inheritDoc}
*/
@Override
@Transactional( "unittree.transactionManager" )
public void removeUsersFromUnit( int nIdUnit )
{
UnitHome.removeUsersFromUnit( nIdUnit );
}
/**
* {@inheritDoc}
*/
@Override
public boolean isMultiAffectationEnabled( )
{
return AppPropertiesService.getPropertyBoolean( PROPERTY_MULTI_AFFECTATION_ENABLED, DEFAULT_MULTI_AFFECTATION_ENABLED );
}
// PRIVATE METHODS
/**
* Tell if 2 users have groups in common
*
* @param user1
* User1
* @param user2
* User2
* @return true or false
*/
private boolean haveCommonWorkgroups( AdminUser user1, AdminUser user2 )
{
ReferenceList workgroups = AdminWorkgroupHome.getUserWorkgroups( user1 );
if ( CollectionUtils.isEmpty( workgroups ) )
{
return true;
}
for ( ReferenceItem item : workgroups )
{
if ( AdminWorkgroupHome.isUserInWorkgroup( user2, item.getCode( ) ) )
{
return true;
}
}
return false;
}
/**
* Check if the user is available
*
* @param currentUser
* the current user
* @param userToCheck
* the user to check
* @param unit
* the unit to check if the user is available for
* @param bMultiAffectationEnabled
* Indicates if this method should allow a user to be in several units, or if it should return false if he is already in a unit.
* @return true if the user is available, false otherwise
*/
private boolean isUserAvailable( AdminUser currentUser, AdminUser userToCheck, Unit unit, boolean bMultiAffectationEnabled )
{
List<Unit> listUnits = _unitService.getUnitsByIdUser( userToCheck.getUserId( ), false );
if ( !bMultiAffectationEnabled && CollectionUtils.isNotEmpty( listUnits ) )
{
return false;
}
for ( Unit userUnit : listUnits )
{
// If the user is in the unit or in one if its parents
if ( ( userUnit.getIdUnit( ) == unit.getIdUnit( ) ) || _unitService.isParent( userUnit, unit ) )
{
return false;
}
}
// Check if the current user is admin => visibility to all users
if ( currentUser.isAdmin( ) )
{
return true;
}
// Check if the current user is parent to the user to check
// Then check if they have the same workgroup, or the user to check does not have any workgroup
return currentUser.isParent( userToCheck )
&& ( haveCommonWorkgroups( currentUser, userToCheck ) || !AdminWorkgroupHome.checkUserHasWorkgroup( userToCheck.getUserId( ) ) );
}
/**
* Get the list of {@link AdminUser} from a given id unit
*
* @param nIdUnit
* the id unit
* @param mapIdUserUnit
* the map of <idUser, Unit>
* @return a list of {@link AdminUser}
*/
private List<AdminUser> getUsers( int nIdUnit, Map<String, Unit> mapIdUserUnit )
{
Unit unit = _unitService.getUnit( nIdUnit, false );
List<AdminUser> listUsers = new ArrayList<>( );
List<Integer> listIdUsers = UnitHome.findIdsUser( nIdUnit );
if ( CollectionUtils.isNotEmpty( listIdUsers ) )
{
for ( int nIdUser : listIdUsers )
{
AdminUser user = AdminUserHome.findByPrimaryKey( nIdUser );
if ( user != null )
{
listUsers.add( user );
mapIdUserUnit.put( Integer.toString( user.getUserId( ) ), unit );
}
}
}
return listUsers;
}
}