CLOUDSTACK-6742: listVolumes - As regularuser , able to list Vms and

volumes of other users.
This commit is contained in:
Min Chen 2014-05-21 16:25:27 -07:00
parent ba848087f8
commit b259bccee7
5 changed files with 17 additions and 364 deletions

View File

@ -199,24 +199,6 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
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
}
@Override
public List<String> listAclGroupsByAccount(Long accountId) {
// TODO Auto-generated method stub
@ -273,12 +255,6 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
}
@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) {
@ -286,13 +262,6 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
}
@Override
public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds, List<Long> revokedIds) {
// TODO Auto-generated method stub
}
@Override
public Long checkAccessAndSpecifyAuthority(Account arg0, Long arg1) {
// TODO Auto-generated method stub

View File

@ -734,9 +734,7 @@ 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>();
List<Long> permittedResources = new ArrayList<Long>();
boolean listAll = cmd.listAll();
Long id = cmd.getId();
@ -744,9 +742,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
Boolean display = cmd.getDisplay();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
cmd.getDomainId(), cmd.isRecursive(), null);
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources,
domainIdRecursiveListProject, listAll, false, "listVirtualMachines");
//Long domainId = domainIdRecursiveListProject.first();
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts,
domainIdRecursiveListProject, listAll, false);
Long domainId = domainIdRecursiveListProject.first();
Boolean isRecursive = domainIdRecursiveListProject.second();
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
@ -768,6 +766,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
SearchBuilder<UserVmJoinVO> sb = _userVmJoinDao.createSearchBuilder();
sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids
_accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
String hypervisor = cmd.getHypervisor();
Object name = cmd.getName();
Object state = cmd.getState();
@ -849,11 +850,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, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria);
// building ACL condition
_accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
if (tags != null && !tags.isEmpty()) {
SearchCriteria<UserVmJoinVO> tagSc = _userVmJoinDao.createSearchCriteria();
@ -1663,9 +1663,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
private Pair<List<VolumeJoinVO>, Integer> searchForVolumesInternal(ListVolumesCmd cmd) {
Account caller = CallContext.current().getCallingAccount();
List<Long> permittedDomains = new ArrayList<Long>();
List<Long> permittedAccounts = new ArrayList<Long>();
List<Long> permittedResources = new ArrayList<Long>();
Long id = cmd.getId();
Long vmInstanceId = cmd.getVirtualMachineId();
@ -1682,9 +1680,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
cmd.getDomainId(), cmd.isRecursive(), null);
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedDomains, permittedAccounts, permittedResources,
domainIdRecursiveListProject, cmd.listAll(), false, "listVolumes");
// Long domainId = domainIdRecursiveListProject.first();
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts,
domainIdRecursiveListProject, cmd.listAll(), false);
Long domainId = domainIdRecursiveListProject.first();
Boolean isRecursive = domainIdRecursiveListProject.second();
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
Filter searchFilter = new Filter(VolumeJoinVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
@ -1698,6 +1696,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
// number of
// records with
// pagination
_accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
@ -1721,10 +1721,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
// now set the SC criteria...
SearchCriteria<VolumeJoinVO> sc = sb.create();
SearchCriteria<VolumeJoinVO> aclSc = _volumeJoinDao.createSearchCriteria();
// building ACL search criteria
_accountMgr.buildACLViewSearchCriteria(sc, aclSc, isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria);
_accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
if (keyword != null) {
SearchCriteria<VolumeJoinVO> ssc = _volumeJoinDao.createSearchCriteria();
@ -1739,7 +1737,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
}
if (display != null) {
sc.setParameters("display", display);
sc.setParameters("displayVolume", display);
}
sc.setParameters("systemUse", 1);

View File

@ -91,9 +91,6 @@ 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);
@ -104,20 +101,6 @@ public interface AccountManager extends AccountService {
void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc,
Long domainId, boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledEntity> sc,
Long domainId, boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds,
List<Long> revokedIds);
// 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

@ -2520,57 +2520,6 @@ 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) {
if (!revokedIds.isEmpty()) {
sb.and("idNIN", sb.entity().getId(), SearchCriteria.Op.NIN);
}
if (permittedAccounts.isEmpty() && domainId == null && listProjectResourcesCriteria == null) {
// caller role authorize him to access everything matching query criteria
return;
}
boolean hasOp = true;
if (!permittedAccounts.isEmpty()) {
sb.and().op("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
} else if (domainId != null) {
if (isRecursive) {
// if accountId isn't specified, we can do a domain match for the
// admin case if isRecursive is true
sb.and().op("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
} else {
sb.and().op("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
}
} else {
hasOp = false;
}
if (listProjectResourcesCriteria != null) {
if (hasOp) {
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);
}
} else {
if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) {
sb.and().op("accountType", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
} else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) {
sb.and().op("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ);
}
}
}
if (!grantedIds.isEmpty()) {
sb.or("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
}
sb.cp();
}
@Override
public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc,
@ -2592,32 +2541,6 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
}
@Override
public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds, List<Long> revokedIds) {
if (!revokedIds.isEmpty()) {
sc.setParameters("idNIN", revokedIds.toArray());
}
if (listProjectResourcesCriteria != null) {
sc.setParameters("accountType", Account.ACCOUNT_TYPE_PROJECT);
}
if (!permittedAccounts.isEmpty()) {
sc.setParameters("accountIdIN", permittedAccounts.toArray());
} else if (domainId != null) {
DomainVO domain = _domainDao.findById(domainId);
if (isRecursive) {
sc.setParameters("domainPath", domain.getPath() + "%");
} else {
sc.setParameters("domainId", domainId);
}
}
if (!grantedIds.isEmpty()) {
sc.setParameters("idIN", grantedIds.toArray());
}
}
@Override
public UserAccount getUserByApiKey(String apiKey) {
@ -2625,196 +2548,6 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
}
@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();
Long accountId = null;
if (id == null) {
// if id is specified, it will ignore all other parameters
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);
}
// specific account is specified, we need to filter contents to only show contents owned by that account.
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 {
AccessType accessType = AccessType.UseEntry;
if (listAll || id != null) {
// listAll = true or id given should show all resources that owner has ListEntry access type.
accessType = AccessType.ListEntry;
}
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".
// assume that there is only one query selector adapter
if (_querySelectors == null || _querySelectors.size() == 0)
return; // no futher filtering
QuerySelector qs = _querySelectors.get(0);
boolean grantedAll = qs.isGrantedAll(caller, action, accessType);
if ( grantedAll ){
if (accountId != null) {
permittedAccounts.add(accountId);
domainIdRecursiveListProject.second(false); // isRecursive is only valid if only domainId is passed.
} else if (domainId != null) {
permittedDomains.add(domainId);
} else {
domainIdRecursiveListProject.second(false); // isRecursive is only valid if only domainId is passed.
}
}
else {
List<Long> grantedDomains = qs.getAuthorizedDomains(caller, action, accessType);
List<Long> grantedAccounts = qs.getAuthorizedAccounts(caller, action, accessType);
List<Long> grantedResources = qs.getAuthorizedResources(caller, action, accessType);
if (accountId != null) {
// specific account filter is specified
if (grantedDomains.contains(domainId)) {
// the account domain is granted to the caller
permittedAccounts.add(accountId);
}
else if (grantedAccounts.contains(accountId)) {
permittedAccounts.add(accountId);
} else {
//TODO: we should also filter granted resources based on accountId passed.
// potential bug, if accountId is passed, it may show some granted resources that may not be owned by that account.
// to fix this, we need to change the interface to also pass ControlledEntity class to use EntityManager to find
// ControlledEntity instance to check accountId. But this has some issues for those non controlled entities,
// like NetworkACLItem
permittedResources.addAll(grantedResources);
}
domainIdRecursiveListProject.second(false); // isRecursive is only valid if only domainId is passed.
} else if (domainId != null) {
// specific domain and no account 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);
}
}
//TODO: we should also filter granted resources based on domainId passed.
// potential bug, if domainId is passed, it may show some granted resources that may not be in that domain.
// to fix this, we need to change the interface to also pass ControlledEntity class to use EntityManager to find
// ControlledEntity instance to check domainId. But this has some issues for those non controlled entities,
// like NetworkACLItem
permittedResources.addAll(grantedResources);
}
} else {
// neither domain nor account is not specified
permittedDomains.addAll(grantedDomains);
permittedAccounts.addAll(grantedAccounts);
permittedResources.addAll(grantedResources);
domainIdRecursiveListProject.second(false); // isRecursive is only valid if only domainId is passed.
}
if (permittedDomains.isEmpty() && permittedAccounts.isEmpty() && permittedResources.isEmpty()) {
// if at this point, all permitted arrays are empty, that means that caller cannot see anything, we put -1 in permittedAccounts
// to distinguish this case from the case that caller can see everything
permittedAccounts.add(-1L);
}
}
}
}
@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) {
// add criteria for project or not
if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) {
sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT);
} else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly) {
sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT);
}
}
if (permittedDomains.isEmpty() && permittedAccounts.isEmpty() && permittedResources.isEmpty())
// can access everything
return;
// 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", SearchCriteria.Op.LIKE, domain.getPath() + "%");
}
} else {
aclSc.addOr("domainId", SearchCriteria.Op.IN, permittedDomains.toArray());
}
}
if (!permittedAccounts.isEmpty()) {
aclSc.addOr("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray());
}
if (!permittedResources.isEmpty()) {
aclSc.addOr("id", SearchCriteria.Op.IN, permittedResources.toArray());
}
sc.addAnd("accountId", SearchCriteria.Op.SC, aclSc);
}
@Override
public List<String> listAclGroupsByAccount(Long accountId) {
if (_querySelectors == null || _querySelectors.size() == 0)

View File

@ -282,26 +282,12 @@ 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) {
// TODO Auto-generated method stub
}
@Override
public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds, List<Long> revokedIds) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see com.cloud.user.AccountService#getUserByApiKey(java.lang.String)
*/
@ -354,22 +340,6 @@ 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
}
@Override
public List<String> listAclGroupsByAccount(Long accountId) {
// TODO Auto-generated method stub