mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-11-04 00:02:37 +01:00 
			
		
		
		
	CLOUDSTACK-1904: API : UI : Admin can not delete Events/Archive from other accounts
This commit is contained in:
		
							parent
							
								
									b17be94cf5
								
							
						
					
					
						commit
						9542f10592
					
				@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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)) {
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -887,10 +887,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);
 | 
			
		||||
 | 
			
		||||
@ -904,10 +914,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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user