Change ListVMsCmd to use new role and entity permission information.

This commit is contained in:
Min Chen 2013-10-09 21:56:52 -07:00
parent f59e47b263
commit 2b4703b6e6
14 changed files with 345 additions and 36 deletions

View File

@ -27,5 +27,7 @@ public interface AclRolePermission extends InternalIdentity {
AccessType getAccessType();
PermissionScope getScope();
boolean isAllowed();
}

View File

@ -20,6 +20,8 @@ import java.util.List;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import com.cloud.utils.Pair;
public interface AclService {
/**
@ -76,6 +78,12 @@ public interface AclService {
List<AclRole> getAclRoles(long accountId);
List<AclGroup> getAclGroups(long accountId);
AclRolePermission getAclRolePermission(long accountId, String entityType, AccessType accessType);
Pair<List<Long>, List<Long>> getAclEntityPermission(long accountId, String entityType, AccessType accessType);
boolean isAPIAccessibleForRoles(String apiName, List<AclRole> roles);
}

View File

@ -1,7 +1,24 @@
package org.apache.cloudstack.acl;
public enum PermissionScope {
ACCOUNT,
DOMAIN,
REGION;
ACCOUNT(1),
DOMAIN(2),
REGION(3);
private int _scale;
private PermissionScope(int scale) {
_scale = scale;
}
public int getScale() {
return _scale;
}
public boolean greaterThan(PermissionScope s) {
if (_scale > s.getScale())
return true;
else
return false;
}
}

View File

@ -41,7 +41,7 @@ public class AclEntityPermissionVO implements AclEntityPermission {
AccessType accessType;
@Column(name = "permission")
private boolean permission;
private boolean allowed;
@Column(name = GenericDao.REMOVED_COLUMN)
private Date removed;
@ -60,7 +60,7 @@ public class AclEntityPermissionVO implements AclEntityPermission {
this.entityId = entityId;
this.entityUuid = entityUuid;
accessType = atype;
this.permission = permission;
allowed = permission;
}
@Override
@ -123,7 +123,11 @@ public class AclEntityPermissionVO implements AclEntityPermission {
@Override
public boolean isAllowed() {
return permission;
return allowed;
}
public void setAllowed(boolean allowed) {
this.allowed = allowed;
}
}

View File

@ -46,8 +46,12 @@ public class AclRolePermissionVO implements AclRolePermission {
@Enumerated(value = EnumType.STRING)
AccessType accessType;
@Column(name = "scope")
@Enumerated(value = EnumType.STRING)
PermissionScope scope;
@Column(name = "permission")
private boolean permission;
private boolean allowed;
public AclRolePermissionVO() {
@ -93,7 +97,21 @@ public class AclRolePermissionVO implements AclRolePermission {
}
@Override
public boolean isAllowed() {
return permission;
public PermissionScope getScope() {
return scope;
}
public void setScope(PermissionScope scope) {
this.scope = scope;
}
@Override
public boolean isAllowed() {
return allowed;
}
public void setAllowed(boolean allowed) {
this.allowed = allowed;
}
}

View File

@ -16,6 +16,8 @@
// under the License.
package org.apache.cloudstack.acl.dao;
import java.util.List;
import org.apache.cloudstack.acl.AclEntityPermissionVO;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
@ -25,4 +27,6 @@ public interface AclEntityPermissionDao extends GenericDao<AclEntityPermissionVO
AclEntityPermissionVO findByGroupAndEntity(long groupId, String entityType, long entityId, AccessType accessType);
List<Long> findEntityIdByGroupAndPermission(long groupId, String entityType, AccessType accessType, boolean isAllowed);
}

View File

@ -16,6 +16,8 @@
// under the License.
package org.apache.cloudstack.acl.dao;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.naming.ConfigurationException;
@ -47,6 +49,7 @@ public class AclEntityPermissionDaoImpl extends GenericDaoBase<AclEntityPermissi
findByGroupEntity.and("entityType", findByGroupEntity.entity().getEntityType(), SearchCriteria.Op.EQ);
findByGroupEntity.and("entityId", findByGroupEntity.entity().getEntityId(), SearchCriteria.Op.EQ);
findByGroupEntity.and("accessType", findByGroupEntity.entity().getAccessType(), SearchCriteria.Op.EQ);
findByGroupEntity.and("allowed", findByGroupEntity.entity().isAllowed(), SearchCriteria.Op.EQ);
findByGroupEntity.done();
return true;
@ -61,4 +64,22 @@ public class AclEntityPermissionDaoImpl extends GenericDaoBase<AclEntityPermissi
sc.setParameters("accessType", accessType);
return findOneBy(sc);
}
@Override
public List<Long> findEntityIdByGroupAndPermission(long groupId, String entityType, AccessType accessType, boolean isAllowed) {
List<Long> idList = new ArrayList<Long>();
SearchCriteria<AclEntityPermissionVO> sc = findByGroupEntity.create();
sc.setParameters("groupId", groupId);
sc.setParameters("entityType", entityType);
sc.setParameters("allowed", isAllowed);
sc.setParameters("accessType", accessType);
List<AclEntityPermissionVO> permList = listBy(sc);
if (permList != null) {
for (AclEntityPermissionVO perm : permList) {
idList.add(perm.getEntityId());
}
}
return idList;
}
}

View File

@ -25,6 +25,10 @@ import com.cloud.utils.db.GenericDao;
public interface AclRolePermissionDao extends GenericDao<AclRolePermissionVO, Long> {
AclRolePermissionVO findByRoleEntityAndPermission(long roleId, String entityType, AccessType accessType, boolean isAllowed);
AclRolePermissionVO findByRoleAndEntity(long roleId, String entityType, AccessType accessType);
List<AclRolePermissionVO> listByRoleAndEntity(long roleId, String entityType, AccessType accessType);
List<AclRolePermissionVO> listByRole(long roleId);

View File

@ -49,11 +49,33 @@ public class AclRolePermissionDaoImpl extends GenericDaoBase<AclRolePermissionVO
findByRoleEntity.or("entityTypeStar", findByRoleEntity.entity().getEntityType(), SearchCriteria.Op.EQ);
findByRoleEntity.cp();
findByRoleEntity.and("accessType", findByRoleEntity.entity().getAccessType(), SearchCriteria.Op.EQ);
findByRoleEntity.and("allowed", findByRoleEntity.entity().isAllowed(), SearchCriteria.Op.EQ);
findByRoleEntity.done();
return true;
}
@Override
public AclRolePermissionVO findByRoleEntityAndPermission(long roleId, String entityType, AccessType accessType, boolean isAllowed) {
SearchCriteria<AclRolePermissionVO> sc = findByRoleEntity.create();
sc.setParameters("roleId", roleId);
sc.setParameters("entityType", entityType);
sc.setParameters("accessType", accessType);
sc.setParameters("entityTypeStar", "*");
sc.setParameters("allowed", isAllowed);
return findOneBy(sc);
}
@Override
public AclRolePermissionVO findByRoleAndEntity(long roleId, String entityType, AccessType accessType) {
SearchCriteria<AclRolePermissionVO> sc = findByRoleEntity.create();
sc.setParameters("roleId", roleId);
sc.setParameters("entityType", entityType);
sc.setParameters("accessType", accessType);
sc.setParameters("entityTypeStar", "*");
return findOneBy(sc);
}
@Override
public List<AclRolePermissionVO> listByRoleAndEntity(long roleId, String entityType, AccessType accessType) {
SearchCriteria<AclRolePermissionVO> sc = findByRoleEntity.create();

View File

@ -30,9 +30,12 @@ import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.acl.AclEntityType;
import org.apache.cloudstack.acl.AclGroup;
import org.apache.cloudstack.acl.AclRole;
import org.apache.cloudstack.acl.AclService;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.acl.dao.AclGroupDao;
import org.apache.cloudstack.acl.dao.AclRoleDao;
import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
@ -349,6 +352,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
@Inject
AclGroupDao _aclGroupDao;
@Inject
AclService _aclService;
/*
* (non-Javadoc)
*
@ -730,6 +736,11 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
Account caller = CallContext.current().getCallingAccount();
List<Long> permittedAccounts = new ArrayList<Long>();
// get granted or denied entity instance permissions
Pair<List<Long>, List<Long>> idPair = _aclService.getAclEntityPermission(caller.getId(), AclEntityType.VM.toString(), AccessType.ListEntry);
List<Long> grantedIds = idPair.first();
List<Long> revokedIds = idPair.second();
boolean listAll = cmd.listAll();
Long id = cmd.getId();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
@ -745,10 +756,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
// first search distinct vm id by using query criteria and pagination
SearchBuilder<UserVmJoinVO> sb = _userVmJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
// ids
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids
_accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
listProjectResourcesCriteria, grantedIds, revokedIds);
Map<String, String> tags = cmd.getTags();
String hypervisor = cmd.getHypervisor();

View File

@ -90,6 +90,9 @@ public interface AccountManager extends AccountService {
void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId,
boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId,
boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds, List<Long> revokedIds);
void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc,
Long domainId, boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
@ -140,7 +143,7 @@ public interface AccountManager extends AccountService {
* @param accountId
* @return account object
*/
Account enableAccount(String accountName, Long domainId, Long accountId);
Account enableAccount(String accountName, Long domainId, Long accountId);
/**
* Deletes user by Id
@ -155,7 +158,7 @@ public interface AccountManager extends AccountService {
* @param userId
* @return UserAccount object
*/
UserAccount updateUser(UpdateUserCmd cmd);
UserAccount updateUser(UpdateUserCmd cmd);
/**
* Disables a user by userId
@ -187,5 +190,5 @@ public interface AccountManager extends AccountService {
* @param accountId
* @return account object
*/
Account lockAccount(String accountName, Long domainId, Long accountId);
Account lockAccount(String accountName, Long domainId, Long accountId);
}

View File

@ -40,12 +40,17 @@ import javax.naming.ConfigurationException;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.AclEntityType;
import org.apache.cloudstack.acl.AclGroupAccountMapVO;
import org.apache.cloudstack.acl.AclRolePermission;
import org.apache.cloudstack.acl.AclService;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.PermissionScope;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.acl.dao.AclGroupAccountMapDao;
import org.apache.cloudstack.acl.dao.AclRolePermissionDao;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
@ -252,6 +257,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
@Inject
private AclGroupAccountMapDao _aclGroupAccountDao;
@Inject
private AclService _aclService;
@Inject
private AclRolePermissionDao _aclRolePermissionDao;
@Inject
public com.cloud.region.ha.GlobalLoadBalancingRulesService _gslbService;
@ -2194,6 +2205,93 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
}
}
// @Override
// public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long>
// permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject,
// boolean listAll, boolean forProjectInvitation) {
// Long domainId = domainIdRecursiveListProject.first();
// if (domainId != null) {
// Domain domain = _domainDao.findById(domainId);
// if (domain == null) {
// throw new InvalidParameterValueException("Unable to find domain by id " + domainId);
// }
// // check permissions
// checkAccess(caller, domain);
// }
//
// if (accountName != null) {
// if (projectId != null) {
// throw new InvalidParameterValueException("Account and projectId can't be specified together");
// }
//
// Account userAccount = null;
// Domain domain = null;
// if (domainId != null) {
// userAccount = _accountDao.findActiveAccount(accountName, domainId);
// domain = _domainDao.findById(domainId);
// } else {
// userAccount = _accountDao.findActiveAccount(accountName, caller.getDomainId());
// domain = _domainDao.findById(caller.getDomainId());
// }
//
// if (userAccount != null) {
// checkAccess(caller, null, false, userAccount);
// //check permissions
// permittedAccounts.add(userAccount.getId());
// } else {
// throw new InvalidParameterValueException("could not find account " + accountName + " in domain " + domain.getUuid());
// }
// }
//
// // set project information
// if (projectId != null) {
// if (!forProjectInvitation) {
// if (projectId.longValue() == -1) {
// if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
// permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId()));
// } else {
// domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.ListProjectResourcesOnly);
// }
// } else {
// Project project = _projectMgr.getProject(projectId);
// if (project == null) {
// throw new InvalidParameterValueException("Unable to find project by id " + projectId);
// }
// if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
// throw new PermissionDeniedException("Account " + caller + " can't access project id=" + projectId);
// }
// permittedAccounts.add(project.getProjectAccountId());
// }
// }
// } else {
// if (id == null) {
// domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources);
// }
// if (permittedAccounts.isEmpty() && domainId == null) {
// if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
// permittedAccounts.add(caller.getId());
// } else if (!listAll) {
// if (id == null) {
// permittedAccounts.add(caller.getId());
// } else if (!isRootAdmin(caller.getId())) {
// domainIdRecursiveListProject.first(caller.getDomainId());
// domainIdRecursiveListProject.second(true);
// }
// } else if (domainId == null) {
// if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
// domainIdRecursiveListProject.first(caller.getDomainId());
// domainIdRecursiveListProject.second(true);
// }
// }
// } else if (domainId != null) {
// if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
// permittedAccounts.add(caller.getId());
// }
// }
//
// }
// }
@Override
public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long>
permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject,
@ -2208,6 +2306,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
checkAccess(caller, domain);
}
if (id != null) {
// look for an individual entity, no other permission criteria are needed
return;
}
if (accountName != null) {
if (projectId != null) {
throw new InvalidParameterValueException("Account and projectId can't be specified together");
@ -2253,34 +2356,27 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
}
}
} else {
if (id == null) {
domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources);
domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources);
// get caller role permission on VM List
AclRolePermission rolePerm = _aclService.getAclRolePermission(caller.getId(), AclEntityType.VM.toString(), AccessType.ListEntry);
if (rolePerm == null) {
// no list entry permission
throw new PermissionDeniedException("Caller has no role permission assigned to list VM");
}
if (permittedAccounts.isEmpty() && domainId == null) {
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
permittedAccounts.add(caller.getId());
} else if (!listAll) {
if (id == null) {
permittedAccounts.add(caller.getId());
} else if (!isRootAdmin(caller.getId())) {
domainIdRecursiveListProject.first(caller.getDomainId());
domainIdRecursiveListProject.second(true);
}
} else if (domainId == null) {
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
domainIdRecursiveListProject.first(caller.getDomainId());
domainIdRecursiveListProject.second(true);
}
}
} else if (domainId != null) {
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
if (permittedAccounts.isEmpty()) {
// no account name is specified
if (rolePerm.getScope() == PermissionScope.ACCOUNT || !listAll) {
// only resource owner can see it, only match account
permittedAccounts.add(caller.getId());
} else {
// match domain tree based on cmd.isRecursive flag or not
domainIdRecursiveListProject.first(caller.getDomainId());
}
}
}
}
@Override
public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId,
boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) {
@ -2304,6 +2400,35 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
}
@Override
public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds, List<Long> revokedIds) {
sb.and().op("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
// if accountId isn't specified, we can do a domain match for the
// admin case if isRecursive is true
sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
}
if (listProjectResourcesCriteria != null) {
if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) {
sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
} else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) {
sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ);
}
}
if (!grantedIds.isEmpty()) {
sb.or("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
}
sb.cp();
if (!revokedIds.isEmpty()) {
sb.and("idNIN", sb.entity().getId(), SearchCriteria.Op.NIN);
}
}
@Override
public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc,
Long domainId, boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) {

View File

@ -18,7 +18,9 @@ package org.apache.cloudstack.acl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ejb.Local;
import javax.inject.Inject;
@ -47,6 +49,7 @@ import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.dao.AccountDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
@ -553,6 +556,67 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
return new ArrayList<AclRole>(roles);
}
@Override
public AclRolePermission getAclRolePermission(long accountId, String entityType, AccessType accessType) {
List<AclRole> roles = getAclRoles(accountId);
AclRolePermission curPerm = null;
for (AclRole role : roles) {
AclRolePermission perm = _rolePermissionDao.findByRoleEntityAndPermission(role.getId(), entityType, accessType, true);
if (perm == null)
continue;
if (curPerm == null) {
curPerm = perm;
} else if (perm.getScope().greaterThan(curPerm.getScope())) {
// pick the more relaxed allowed permission
curPerm = perm;
}
}
return curPerm;
}
@Override
public List<AclGroup> getAclGroups(long accountId) {
GenericSearchBuilder<AclGroupAccountMapVO, Long> groupSB = _aclGroupAccountMapDao.createSearchBuilder(Long.class);
groupSB.selectField(groupSB.entity().getAclGroupId());
groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ);
SearchCriteria<Long> groupSc = groupSB.create();
List<Long> groupIds = _aclGroupAccountMapDao.customSearch(groupSc, null);
SearchBuilder<AclGroupVO> sb = _aclGroupDao.createSearchBuilder();
sb.and("ids", sb.entity().getId(), Op.IN);
SearchCriteria<AclGroupVO> sc = sb.create();
sc.setParameters("ids", groupIds.toArray(new Object[groupIds.size()]));
List<AclGroupVO> groups = _aclGroupDao.search(sc, null);
return new ArrayList<AclGroup>(groups);
}
@Override
public Pair<List<Long>, List<Long>> getAclEntityPermission(long accountId, String entityType, AccessType accessType) {
List<AclGroup> groups = getAclGroups(accountId);
if (groups == null || groups.size() == 0) {
return new Pair<List<Long>, List<Long>>(new ArrayList<Long>(), new ArrayList<Long>());
}
Set<Long> allowedIds = new HashSet<Long>();
Set<Long> deniedIds = new HashSet<Long>();
for (AclGroup grp : groups) {
// get allowed id and denied list for each group
List<Long> allowedIdList = _entityPermissionDao.findEntityIdByGroupAndPermission(grp.getId(), entityType, accessType, true);
if (allowedIdList != null) {
allowedIds.addAll(allowedIdList);
}
List<Long> deniedIdList = _entityPermissionDao.findEntityIdByGroupAndPermission(grp.getId(), entityType, accessType, false);
if (deniedIdList != null) {
deniedIds.addAll(deniedIdList);
}
}
return new Pair<List<Long>, List<Long>>(new ArrayList<Long>(allowedIds), new ArrayList<Long>(deniedIds))
;
}
@Override
public boolean isAPIAccessibleForRoles(String apiName, List<AclRole> roles) {

View File

@ -286,6 +286,13 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
// TODO Auto-generated method stub
}
@Override
public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds, List<Long> revokedIds) {
// TODO Auto-generated method stub
}
@Override
public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc, Long domainId,
boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) {