package net.techreadiness.persistence.datagrid; import java.util.List; import javax.inject.Inject; import net.techreadiness.persistence.criteriaquery.Criteria; import net.techreadiness.persistence.criteriaquery.CriteriaQuery; import net.techreadiness.persistence.criteriaquery.QueryResult; import net.techreadiness.persistence.domain.UserDO; import net.techreadiness.security.CorePermissionCodes; import net.techreadiness.security.PermissionCode; import net.techreadiness.service.ServiceContext; import net.techreadiness.service.UserService; import net.techreadiness.service.common.DataGrid; import net.techreadiness.service.common.DataGridItemProviderImpl; import net.techreadiness.service.object.Scope; import net.techreadiness.service.object.User; import net.techreadiness.service.object.mapping.MappingService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @Component @org.springframework.context.annotation.Scope("prototype") @Transactional(readOnly = true) public class UserByScopeItemProviderImpl extends DataGridItemProviderImpl<User> implements UserByScopeItemProvider { private static final String SHOW_DELETED = "SHOW_DELETED"; private static final String ORG_FILTER_KEY = "orgId"; private static final String ROLE_FILTER_KEY = "roleId"; private Scope scope; private ServiceContext serviceContext; PermissionCode[] ignoreConferPerm = { CorePermissionCodes.CORE_SEARCH_IGNORE_ROLECONFER }; @Inject MappingService mappingService; @Inject UserService userService; @Autowired CriteriaQuery<UserDO> criteriaQuery; @Override public List<User> getPage(DataGrid<User> grid) { boolean showDeleted = false; if (grid.getFilters().containsKey(SHOW_DELETED)) { showDeleted = true; } Criteria criteria = createCriteria(grid, SHOW_DELETED); criteriaQuery.setFullTextSearchColumns(new String[] { "username", "first_name", "last_name" }); // Create the base query to limit to non deleted users within the user's scope. StringBuilder sb = new StringBuilder(); sb.append(" select * from user "); if (showDeleted) { sb.append(" where scope_id=:scope_id"); } else { sb.append(" where delete_date is null and scope_id=:scope_id"); } criteria.getParameters().put("scope_id", scope.getScopeId().toString()); // Filter by the organizations to which the user is associated. if (grid.getFilters().containsKey(ORG_FILTER_KEY)) { sb.append(" and user_id in (select user_id from user_org where org_id in (:" + ORG_FILTER_KEY + ")) "); criteria.getParameters().putAll(ORG_FILTER_KEY, grid.getFilters().get(ORG_FILTER_KEY)); } else { // if no org filter, constrain by global org. sb.append(" and user_id in (select uo.user_id from user_org uo, org_tree ot "); sb.append(" where ot.ancestor_org_id = :org_id "); sb.append(" and ot.org_id = uo.org_id ) "); criteria.getParameters().put("org_id", serviceContext.getOrgId().toString()); } // Filter by the roles. if (grid.getFilters().containsKey(ROLE_FILTER_KEY)) { sb.append(" and user_id in (select user_id from user_role where role_id in (:" + ROLE_FILTER_KEY + ")) "); criteria.getParameters().putAll(ROLE_FILTER_KEY, grid.getFilters().get(ROLE_FILTER_KEY)); } if (!userService.hasPermission(serviceContext, ignoreConferPerm)) { // Constrain by conferrability // this basically says, only those searched for users that have a role that matches a delegated role that was // found // from any of the current user's roles. sb.append(" and user_id in (select u.user_id from user u, user_role ur "); sb.append(" where u.user_id = ur.user_id "); sb.append(" and ur.role_id in ( select rd.delegated_role_id from role_delegation rd, user_role uur "); sb.append(" where rd.role_id = uur.role_id"); sb.append(" and uur.user_id = :user_id ) ) "); criteria.getParameters().put("user_id", serviceContext.getUserId().toString()); } criteriaQuery.setBaseSubSelect(sb.toString()); QueryResult<UserDO> result = criteriaQuery.getData(criteria, UserDO.class); setTotalNumberOfItems(result.getTotalRowCount()); return mappingService.mapFromDOList(result.getRows()); } @Override public void setScope(Scope scope) { this.scope = scope; } public Scope getScope() { return scope; } @Override public void setServiceContext(ServiceContext serviceContext) { this.serviceContext = serviceContext; } @Override public User getObjectForKey(String rowKey) { Long userId = Long.valueOf(rowKey); return userService.getById(serviceContext, userId); } }