QueryChecker interface and ACL search criteria to be used for query api

for entities with db views created.
This commit is contained in:
Min Chen 2013-11-22 16:36:38 -08:00
parent 9d0d96225d
commit 11c0c263f2
8 changed files with 201 additions and 42 deletions

View File

@ -20,8 +20,8 @@ import java.util.List;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import com.cloud.utils.Pair;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
public interface AclService {
@ -89,4 +89,10 @@ public interface AclService {
List<AclRole> getEffectiveRoles(Account caller, ControlledEntity entity);
List<Long> getGrantedDomains(long accountId, AclEntityType entityType, String action);
List<Long> getGrantedAccounts(long accountId, AclEntityType entityType, String action);
List<Long> getGrantedResources(long accountId, AclEntityType entityType, String action);
}

View File

@ -35,15 +35,6 @@ public interface QueryChecker extends Adapter {
*/
List<Long> getAuthorizedDomains(Account caller, AclEntityType entityType);
/**
* List denied domains for the caller, given a specific entity type.
*
* @param caller account to check against.
* @param entityType entity type
* @return list of domain Ids granted to the caller account.
*/
List<Long> getDeniedDomains(Account caller, AclEntityType entityType);
/**
* List granted accounts for the caller, given a specific entity type.
*
@ -53,14 +44,6 @@ public interface QueryChecker extends Adapter {
*/
List<Long> getAuthorizedAccounts(Account caller, AclEntityType entityType);
/**
* List denied accounts for the caller, given a specific entity type.
*
* @param caller account to check against.
* @param entityType entity type
* @return list of domain Ids granted to the caller account.
*/
List<Long> getDeniedAccounts(Account caller, AclEntityType entityType);
/**
* List granted resources for the caller, given a specific entity type.
@ -71,13 +54,5 @@ public interface QueryChecker extends Adapter {
*/
List<Long> getAuthorizedResources(Account caller, AclEntityType entityType);
/**
* List denied resources for the caller, given a specific entity type.
*
* @param caller account to check against.
* @param entityType entity type
* @return list of domain Ids granted to the caller account.
*/
List<Long> getDeniedResources(Account caller, AclEntityType entityType);
}

View File

@ -397,6 +397,22 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
// TODO Auto-generated method stub
return false;
}
@Override
public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long> permittedDomains, List<Long> permittedAccounts,
List<Long> permittedResources, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation,
String action) {
// TODO Auto-generated method stub
}
@Override
public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, SearchCriteria<? extends ControlledEntity> aclSc, boolean isRecursive,
List<Long> permittedDomains, List<Long> permittedAccounts, List<Long> permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) {
// TODO Auto-generated method stub
}
}

View File

@ -29,12 +29,10 @@ 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;
@ -749,20 +747,17 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
private Pair<List<UserVmJoinVO>, Integer> searchForUserVMsInternal(ListVMsCmd cmd) {
Account caller = CallContext.current().getCallingAccount();
List<Long> permittedDomains = new ArrayList<Long>();
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();
List<Long> permittedResources = new ArrayList<Long>();
boolean listAll = cmd.listAll();
Long id = cmd.getId();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
cmd.getDomainId(), cmd.isRecursive(), null);
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts,
domainIdRecursiveListProject, listAll, false);
Long domainId = domainIdRecursiveListProject.first();
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources,
domainIdRecursiveListProject, listAll, false, "listVirtualMachines");
//Long domainId = domainIdRecursiveListProject.first();
Boolean isRecursive = domainIdRecursiveListProject.second();
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
@ -773,10 +768,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
SearchBuilder<UserVmJoinVO> sb = _userVmJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids
// build acl search builder condition
_accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria, grantedIds, revokedIds);
Map<String, String> tags = cmd.getTags();
String hypervisor = cmd.getHypervisor();
Object name = cmd.getName();
@ -854,10 +845,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
// populate the search criteria with the values passed in
SearchCriteria<UserVmJoinVO> sc = sb.create();
SearchCriteria<UserVmJoinVO> aclSc = _userVmJoinDao.createSearchCriteria();
// building ACL search criteria
_accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria, grantedIds, revokedIds);
_accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria);
if (tags != null && !tags.isEmpty()) {
SearchCriteria<UserVmJoinVO> tagSc = _userVmJoinDao.createSearchCriteria();

View File

@ -107,6 +107,15 @@ public interface AccountManager extends AccountService {
void buildACLSearchParameters(Account caller, Long id,
String accountName, Long projectId, List<Long> permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation);
// new ACL model routine for query api based on db views
void buildACLSearchParameters(Account caller, Long id,
String accountName, Long projectId, List<Long> permittedDomains, List<Long> permittedAccounts, List<Long> permittedResources,
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation, String action);
void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, SearchCriteria<? extends ControlledEntity> aclSc, boolean isRecursive,
List<Long> permittedDomains, List<Long> permittedAccounts,
List<Long> permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria);
/**
* Deletes a user by userId
*

View File

@ -2537,4 +2537,132 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
return _userAccountDao.getUserByApiKey(apiKey);
}
@Override
public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long> permittedDomains, List<Long> permittedAccounts,
List<Long> permittedResources, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation,
String action) {
Long domainId = domainIdRecursiveListProject.first();
if (domainId != null) {
// look for entity in the given domain
Domain domain = _domainDao.findById(domainId);
if (domain == null) {
throw new InvalidParameterValueException("Unable to find domain by id " + domainId);
}
// check permissions
checkAccess(caller, domain);
}
if (id != null) {
// look for an individual entity, no other permission criteria are needed
permittedResources.add(id);
return;
}
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) {
//check permissions
checkAccess(caller, null, false, userAccount);
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 (isNormalUser(caller.getId())) {
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 {
domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources);
// search for policy permissions associated with caller to get all his authorized domains, accounts, and resources
// Assumption: if a domain is in grantedDomains, then all the accounts under this domain will not be returned in "grantedAccounts". Similarly, if an account
// is in grantedAccounts, then all the resources owned by this account will not be returned in "grantedResources".
List<Long> grantedDomains = _aclService.getGrantedDomains(caller.getId(), AclEntityType.VM, action);
List<Long> grantedAccounts = _aclService.getGrantedAccounts(caller.getId(), AclEntityType.VM, action);
List<Long> grantedResources = _aclService.getGrantedResources(caller.getId(), AclEntityType.VM, action);
if (domainId != null) {
// specific domain is specified
if (grantedDomains.contains(domainId)) {
permittedDomains.add(domainId);
} else {
for (Long acctId : grantedAccounts) {
Account acct = _accountDao.findById(acctId);
if (acct != null && acct.getDomainId() == domainId) {
permittedAccounts.add(acctId);
}
}
permittedResources.addAll(grantedResources);
}
} else if (permittedAccounts.isEmpty()) {
// neither domain nor account is not specified
permittedDomains.addAll(grantedDomains);
permittedAccounts.addAll(grantedAccounts);
permittedResources.addAll(grantedResources);
}
}
}
@Override
public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, SearchCriteria<? extends ControlledEntity> aclSc, boolean isRecursive,
List<Long> permittedDomains,
List<Long> permittedAccounts, List<Long> permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) {
if (listProjectResourcesCriteria != null) {
sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT);
}
// Note that this may have limitations on number of permitted domains, accounts, or resource ids are allowed due to sql package size limitation
if (!permittedDomains.isEmpty()) {
if (isRecursive) {
for (int i = 0; i < permittedDomains.size(); i++) {
Domain domain = _domainDao.findById(permittedDomains.get(i));
aclSc.addOr("domainPath" + i, SearchCriteria.Op.LIKE, domain.getPath() + "%");
}
} else {
aclSc.addOr("domainIdIN", SearchCriteria.Op.IN, permittedDomains.toArray());
}
}
if (!permittedAccounts.isEmpty()) {
aclSc.addOr("accountIdIN", SearchCriteria.Op.IN, permittedAccounts.toArray());
}
if (!permittedResources.isEmpty()) {
aclSc.addOr("idIn", SearchCriteria.Op.IN, permittedResources.toArray());
}
sc.addAnd("accountIdIn", SearchCriteria.Op.SC, aclSc);
}
}

View File

@ -689,4 +689,22 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
return roles;
}
@Override
public List<Long> getGrantedDomains(long accountId, AclEntityType entityType, String action) {
// TODO Auto-generated method stub
return null;
}
@Override
public List<Long> getGrantedAccounts(long accountId, AclEntityType entityType, String action) {
// TODO Auto-generated method stub
return null;
}
@Override
public List<Long> getGrantedResources(long accountId, AclEntityType entityType, String action) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -362,4 +362,20 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
return false;
}
@Override
public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long> permittedDomains, List<Long> permittedAccounts,
List<Long> permittedResources, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation,
String action) {
// TODO Auto-generated method stub
}
@Override
public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, SearchCriteria<? extends ControlledEntity> aclSc, boolean isRecursive,
List<Long> permittedDomains, List<Long> permittedAccounts, List<Long> permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) {
// TODO Auto-generated method stub
}
}