CLOUDSTACK-1904: API : UI : Admin can not delete Events/Archive from other accounts

This commit is contained in:
Sanjay Tripathi 2013-04-26 16:47:56 +05:30 committed by Edison Su
parent 50eeae81da
commit 88422248cc
9 changed files with 77 additions and 27 deletions

View File

@ -25,7 +25,6 @@ import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.AlertResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.log4j.Logger;

View File

@ -26,9 +26,10 @@ public interface DomainDao extends GenericDao<DomainVO, Long> {
public DomainVO create(DomainVO domain);
public DomainVO findDomainByPath(String domainPath);
public boolean isChildDomain(Long parentId, Long childId);
DomainVO findImmediateChildForParent(Long parentId);
List<DomainVO> findImmediateChildrenForParent(Long parentId);
List<DomainVO> findAllChildren(String path, Long parentId);
List<DomainVO> findInactiveDomains();
DomainVO findImmediateChildForParent(Long parentId);
List<DomainVO> findImmediateChildrenForParent(Long parentId);
List<DomainVO> findAllChildren(String path, Long parentId);
List<DomainVO> findInactiveDomains();
Set<Long> getDomainParentIds(long domainId);
List<Long> getDomainChildrenIds(String path);
}

View File

@ -32,6 +32,7 @@ import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
@ -46,6 +47,7 @@ public class DomainDaoImpl extends GenericDaoBase<DomainVO, Long> implements Dom
protected SearchBuilder<DomainVO> DomainPairSearch;
protected SearchBuilder<DomainVO> ImmediateChildDomainSearch;
protected SearchBuilder<DomainVO> FindAllChildrenSearch;
protected GenericSearchBuilder<DomainVO, Long> FindIdsOfAllChildrenSearch;
protected SearchBuilder<DomainVO> AllFieldsSearch;
public DomainDaoImpl () {
@ -70,7 +72,12 @@ public class DomainDaoImpl extends GenericDaoBase<DomainVO, Long> implements Dom
FindAllChildrenSearch.and("path", FindAllChildrenSearch.entity().getPath(), SearchCriteria.Op.LIKE);
FindAllChildrenSearch.and("id", FindAllChildrenSearch.entity().getId(), SearchCriteria.Op.NEQ);
FindAllChildrenSearch.done();
FindIdsOfAllChildrenSearch = createSearchBuilder(Long.class);
FindIdsOfAllChildrenSearch.selectField(FindIdsOfAllChildrenSearch.entity().getId());
FindIdsOfAllChildrenSearch.and("path", FindIdsOfAllChildrenSearch.entity().getPath(), SearchCriteria.Op.LIKE);
FindIdsOfAllChildrenSearch.done();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), SearchCriteria.Op.EQ);
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
@ -221,7 +228,14 @@ public class DomainDaoImpl extends GenericDaoBase<DomainVO, Long> implements Dom
sc.setParameters("id", parentId);
return listBy(sc);
}
@Override
public List<Long> getDomainChildrenIds(String path){
SearchCriteria<Long> sc = FindIdsOfAllChildrenSearch.create();
sc.setParameters("path", path+"%");
return customSearch(sc, null);
}
@Override
public boolean isChildDomain(Long parentId, Long childId) {
if ((parentId == null) || (childId == null)) {

View File

@ -31,7 +31,7 @@ public interface EventDao extends GenericDao<EventVO, Long> {
EventVO findCompletedEvent(long startId);
public List<EventVO> listToArchiveOrDeleteEvents(List<Long> ids, String type, Date olderThan, Long accountId);
public List<EventVO> listToArchiveOrDeleteEvents(List<Long> ids, String type, Date olderThan, List<Long> accountIds);
public void archiveEvents(List<EventVO> events);

View File

@ -49,7 +49,7 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements Event
ToArchiveOrDeleteEventSearch = createSearchBuilder();
ToArchiveOrDeleteEventSearch.and("id", ToArchiveOrDeleteEventSearch.entity().getId(), Op.IN);
ToArchiveOrDeleteEventSearch.and("type", ToArchiveOrDeleteEventSearch.entity().getType(), Op.EQ);
ToArchiveOrDeleteEventSearch.and("accountId", ToArchiveOrDeleteEventSearch.entity().getAccountId(), Op.EQ);
ToArchiveOrDeleteEventSearch.and("accountIds", ToArchiveOrDeleteEventSearch.entity().getAccountId(), Op.IN);
ToArchiveOrDeleteEventSearch.and("createDateL", ToArchiveOrDeleteEventSearch.entity().getCreateDate(), Op.LT);
ToArchiveOrDeleteEventSearch.done();
}
@ -76,7 +76,7 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements Event
}
@Override
public List<EventVO> listToArchiveOrDeleteEvents(List<Long> ids, String type, Date olderThan, Long accountId) {
public List<EventVO> listToArchiveOrDeleteEvents(List<Long> ids, String type, Date olderThan, List<Long> accountIds) {
SearchCriteria<EventVO> sc = ToArchiveOrDeleteEventSearch.create();
if (ids != null) {
sc.setParameters("id", ids.toArray(new Object[ids.size()]));
@ -87,23 +87,24 @@ public class EventDaoImpl extends GenericDaoBase<EventVO, Long> implements Event
if (olderThan != null) {
sc.setParameters("createDateL", olderThan);
}
if (accountId != null) {
sc.setParameters("accountId", accountId);
if (accountIds != null && !accountIds.isEmpty()) {
sc.setParameters("accountIds", accountIds.toArray(new Object[accountIds.size()]));
}
return search(sc, null);
}
@Override
public void archiveEvents(List<EventVO> events) {
Transaction txn = Transaction.currentTxn();
txn.start();
for (EventVO event : events) {
event = lockRow(event.getId(), true);
event.setArchived(true);
update(event.getId(), event);
txn.commit();
if (events != null && !events.isEmpty()) {
Transaction txn = Transaction.currentTxn();
txn.start();
for (EventVO event : events) {
event = lockRow(event.getId(), true);
event.setArchived(true);
update(event.getId(), event);
txn.commit();
}
txn.close();
}
txn.close();
}
}

View File

@ -49,4 +49,5 @@ public interface AccountDao extends GenericDao<AccountVO, Long> {
//returns only non-removed account
Account findActiveAccount(String accountName, Long domainId);
Account findActiveNonProjectAccount(String accountName, Long domainId);
List<Long> getAccountIdsForDomains(List<Long> ids);
}

View File

@ -35,8 +35,10 @@ import com.cloud.utils.Pair;
import com.cloud.utils.crypt.DBEncryptionUtil;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
@Component
@ -54,7 +56,8 @@ public class AccountDaoImpl extends GenericDaoBase<AccountVO, Long> implements A
protected final SearchBuilder<AccountVO> CleanupForRemovedAccountsSearch;
protected final SearchBuilder<AccountVO> CleanupForDisabledAccountsSearch;
protected final SearchBuilder<AccountVO> NonProjectAccountSearch;
protected final GenericSearchBuilder<AccountVO, Long> AccountIdsSearch;
public AccountDaoImpl() {
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("accountName", AllFieldsSearch.entity().getAccountName(), SearchCriteria.Op.EQ);
@ -91,6 +94,11 @@ public class AccountDaoImpl extends GenericDaoBase<AccountVO, Long> implements A
NonProjectAccountSearch.and("state", NonProjectAccountSearch.entity().getState(), SearchCriteria.Op.EQ);
NonProjectAccountSearch.and("type", NonProjectAccountSearch.entity().getType(), SearchCriteria.Op.NEQ);
NonProjectAccountSearch.done();
AccountIdsSearch = createSearchBuilder(Long.class);
AccountIdsSearch.selectField(AccountIdsSearch.entity().getId());
AccountIdsSearch.and("ids", AccountIdsSearch.entity().getDomainId(), Op.IN);
AccountIdsSearch.done();
}
@Override
@ -263,5 +271,12 @@ public class AccountDaoImpl extends GenericDaoBase<AccountVO, Long> implements A
}
}
}
@Override
public List<Long> getAccountIdsForDomains(List<Long> domainIds) {
SearchCriteria<Long> sc = AccountIdsSearch.create();
sc.setParameters("ids", domainIds.toArray(new Object[domainIds.size()]));
return customSearch(sc, null);
}
}

View File

@ -957,10 +957,20 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
@Override
public boolean archiveEvents(ArchiveEventsCmd cmd) {
Account caller = UserContext.current().getCaller();
List<Long> ids = cmd.getIds();
boolean result =true;
List<Long> permittedAccountIds = new ArrayList<Long>();
List<EventVO> events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), cmd.getEntityOwnerId());
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL && caller.getType() == Account.ACCOUNT_TYPE_PROJECT) {
permittedAccountIds.add(caller.getId());
} else {
DomainVO domain = _domainDao.findById(caller.getDomainId());
List<Long> permittedDomainIds = _domainDao.getDomainChildrenIds(domain.getPath());
permittedAccountIds = _accountDao.getAccountIdsForDomains(permittedDomainIds);
}
List<EventVO> events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), permittedAccountIds);
ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]);
_accountMgr.checkAccess(UserContext.current().getCaller(), null, true, sameOwnerEvents);
@ -974,10 +984,20 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
@Override
public boolean deleteEvents(DeleteEventsCmd cmd) {
Account caller = UserContext.current().getCaller();
List<Long> ids = cmd.getIds();
boolean result =true;
List<Long> permittedAccountIds = new ArrayList<Long>();
List<EventVO> events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), cmd.getEntityOwnerId());
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL || caller.getType() == Account.ACCOUNT_TYPE_PROJECT) {
permittedAccountIds.add(caller.getId());
} else {
DomainVO domain = _domainDao.findById(caller.getDomainId());
List<Long> permittedDomainIds = _domainDao.getDomainChildrenIds(domain.getPath());
permittedAccountIds = _accountDao.getAccountIdsForDomains(permittedDomainIds);
}
List<EventVO> events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), permittedAccountIds);
ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]);
_accountMgr.checkAccess(UserContext.current().getCaller(), null, true, sameOwnerEvents);

View File

@ -18,7 +18,6 @@ package com.cloud.event;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyList;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
@ -58,7 +57,7 @@ public class EventControlsUnitTest extends TestCase{
_mgmtServer._eventDao = _eventDao;
_mgmtServer._accountMgr = _accountMgr;
doNothing().when(_accountMgr).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class));
when(_eventDao.listToArchiveOrDeleteEvents(anyList(), anyString(), any(Date.class), anyLong())).thenReturn(_events);
when(_eventDao.listToArchiveOrDeleteEvents(anyList(), anyString(), any(Date.class), anyList())).thenReturn(_events);
}
@After