use of com.cloud.acl.SecurityChecker in project cosmic by MissionCriticalCloud.
the class AccountManagerImpl method checkAccess.
@Override
public void checkAccess(final Account caller, final AccessType accessType, final boolean sameOwner, final String apiName, final ControlledEntity... entities) {
// check for the same owner
Long ownerId = null;
ControlledEntity prevEntity = null;
if (sameOwner) {
for (final ControlledEntity entity : entities) {
if (sameOwner) {
if (ownerId == null) {
ownerId = entity.getAccountId();
} else if (ownerId.longValue() != entity.getAccountId()) {
throw new PermissionDeniedException("Entity " + entity + " and entity " + prevEntity + " belong to different accounts");
}
prevEntity = entity;
}
}
}
if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || isRootAdmin(caller.getId())) {
// no need to make permission checks if the system/root admin makes the call
if (s_logger.isTraceEnabled()) {
s_logger.trace("No need to make permission check for System/RootAdmin account, returning true");
}
return;
}
final HashMap<Long, List<ControlledEntity>> domains = new HashMap<>();
for (final ControlledEntity entity : entities) {
long domainId = entity.getDomainId();
if (entity.getAccountId() != -1 && domainId == -1) {
// If account exists domainId should too so calculate
// it. This condition might be hit for templates or entities which miss domainId in their tables
final Account account = ApiDBUtils.findAccountById(entity.getAccountId());
domainId = account != null ? account.getDomainId() : -1;
}
if (entity.getAccountId() != -1 && domainId != -1 && !(entity instanceof VirtualMachineTemplate) && !(entity instanceof Network && accessType != null && accessType == AccessType.UseEntry) && !(entity instanceof AffinityGroup)) {
List<ControlledEntity> toBeChecked = domains.get(entity.getDomainId());
// for templates, we don't have to do cross domains check
if (toBeChecked == null) {
toBeChecked = new ArrayList<>();
domains.put(domainId, toBeChecked);
}
toBeChecked.add(entity);
}
boolean granted = false;
for (final SecurityChecker checker : _securityCheckers) {
if (checker.checkAccess(caller, entity, accessType, apiName)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Access to " + entity + " granted to " + caller + " by " + checker.getName());
}
granted = true;
break;
}
}
if (!granted) {
assert false : "How can all of the security checkers pass on checking this check: " + entity;
throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + entity);
}
}
for (final Map.Entry<Long, List<ControlledEntity>> domain : domains.entrySet()) {
for (final SecurityChecker checker : _securityCheckers) {
final Domain d = _domainMgr.getDomain(domain.getKey());
if (d == null || d.getRemoved() != null) {
throw new PermissionDeniedException("Domain is not found.", caller, domain.getValue());
}
try {
checker.checkAccess(caller, d);
} catch (final PermissionDeniedException e) {
e.addDetails(caller, domain.getValue());
throw e;
}
}
}
// check that resources belong to the same account
}
Aggregations