Skip to content

Commit ef7debb

Browse files
DaanHooglandsureshanapartiDaan HooglandjoseflauzinoGutoVeronezi
authored
Filter usage for project (apache#5866)
Co-authored-by: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com> Co-authored-by: Daan Hoogland <dahn@onecht.net> Co-authored-by: José Flauzino <jose.wilson.vf@gmail.com> Co-authored-by: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com> Co-authored-by: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com>
1 parent 26e4e18 commit ef7debb

1 file changed

Lines changed: 60 additions & 44 deletions

File tree

server/src/main/java/com/cloud/usage/UsageServiceImpl.java

Lines changed: 60 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@
3636
import org.apache.cloudstack.usage.Usage;
3737
import org.apache.cloudstack.usage.UsageService;
3838
import org.apache.cloudstack.usage.UsageTypes;
39+
import org.apache.commons.lang3.StringUtils;
3940
import org.apache.log4j.Logger;
41+
import org.jetbrains.annotations.NotNull;
4042
import org.springframework.stereotype.Component;
4143

4244
import com.cloud.configuration.Config;
@@ -166,46 +168,27 @@ public Pair<List<? extends Usage>, Integer> getUsageRecords(ListUsageRecordsCmd
166168
Long accountId = cmd.getAccountId();
167169
Long domainId = cmd.getDomainId();
168170
String accountName = cmd.getAccountName();
169-
Account userAccount = null;
170171
Account caller = CallContext.current().getCallingAccount();
171172
Long usageType = cmd.getUsageType();
172173
Long projectId = cmd.getProjectId();
173174
String usageId = cmd.getUsageId();
175+
boolean projectRequested = false;
174176

175177
if (projectId != null) {
176178
if (accountId != null) {
177179
throw new InvalidParameterValueException("Projectid and accountId can't be specified together");
178180
}
179-
Project project = _projectMgr.getProject(projectId);
180-
if (project == null) {
181-
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
182-
}
183-
accountId = project.getProjectAccountId();
184-
}
185-
186-
//if accountId is not specified, use accountName and domainId
187-
if ((accountId == null) && (accountName != null) && (domainId != null)) {
188-
if (_domainDao.isChildDomain(caller.getDomainId(), domainId)) {
189-
Filter filter = new Filter(AccountVO.class, "id", Boolean.FALSE, null, null);
190-
List<AccountVO> accounts = _accountDao.listAccounts(accountName, domainId, filter);
191-
if (accounts.size() > 0) {
192-
userAccount = accounts.get(0);
193-
}
194-
if (userAccount != null) {
195-
accountId = userAccount.getId();
196-
} else {
197-
throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
198-
}
199-
} else {
200-
throw new PermissionDeniedException("Invalid Domain Id or Account");
201-
}
181+
accountId = getAccountIdFromProject(projectId);
182+
projectRequested = true;
183+
} else if ((accountId == null) && (StringUtils.isNotBlank(accountName)) && (domainId != null)) {
184+
accountId = getAccountIdFromDomainPlusName(domainId, accountName, caller);
202185
}
203186

204187
boolean ignoreAccountId = false;
205188
boolean isDomainAdmin = _accountService.isDomainAdmin(caller.getId());
206189
boolean isNormalUser = _accountService.isNormalUser(caller.getId());
207190

208-
//If accountId couldn't be found using accountName and domainId, get it from userContext
191+
//If accountId couldn't be found using project or accountName and domainId, get it from userContext
209192
if (accountId == null) {
210193
accountId = caller.getId();
211194
//List records for all the accounts if the caller account is of type admin.
@@ -215,22 +198,7 @@ public Pair<List<? extends Usage>, Integer> getUsageRecords(ListUsageRecordsCmd
215198
}
216199

217200
// Check if a domain admin is allowed to access the requested domain id
218-
if (isDomainAdmin) {
219-
if (domainId != null) {
220-
Account callerAccount = _accountService.getAccount(caller.getId());
221-
Domain domain = _domainDao.findById(domainId);
222-
_accountService.checkAccess(callerAccount, domain);
223-
} else {
224-
// Domain admins can only access their own domain's usage records.
225-
// Set the domain if not specified.
226-
domainId = caller.getDomainId();
227-
}
228-
229-
if (cmd.getAccountId() != null) {
230-
// Check if a domain admin is allowed to access the requested account info.
231-
checkDomainAdminAccountAccess(accountId, domainId);
232-
}
233-
}
201+
domainId = getDomainScopeForQuery(cmd, accountId, domainId, caller, isDomainAdmin);
234202

235203
// By default users do not have access to this API.
236204
// Adding checks here in case someone changes the default access.
@@ -255,9 +223,7 @@ public Pair<List<? extends Usage>, Integer> getUsageRecords(ListUsageRecordsCmd
255223
SearchCriteria<UsageVO> sc = _usageDao.createSearchCriteria();
256224

257225
if (accountId != -1 && accountId != Account.ACCOUNT_ID_SYSTEM && !ignoreAccountId) {
258-
// account exists and either domain on user role
259-
// If not recursive and the account belongs to the user/domain admin, or the account was passed in, filter
260-
if ((accountId == caller.getId() && !cmd.isRecursive()) || cmd.getAccountId() != null){
226+
if (!cmd.isRecursive() || cmd.getAccountId() != null || projectRequested){
261227
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
262228
}
263229
}
@@ -397,6 +363,56 @@ public Pair<List<? extends Usage>, Integer> getUsageRecords(ListUsageRecordsCmd
397363
return new Pair<List<? extends Usage>, Integer>(usageRecords.first(), usageRecords.second());
398364
}
399365

366+
private Long getDomainScopeForQuery(ListUsageRecordsCmd cmd, Long accountId, Long domainId, Account caller, boolean isDomainAdmin) {
367+
if (isDomainAdmin) {
368+
if (domainId != null) {
369+
Account callerAccount = _accountService.getAccount(caller.getId());
370+
Domain domain = _domainDao.findById(domainId);
371+
_accountService.checkAccess(callerAccount, domain);
372+
} else {
373+
domainId = caller.getDomainId();
374+
}
375+
376+
if (cmd.getAccountId() != null) {
377+
checkDomainAdminAccountAccess(accountId, domainId);
378+
}
379+
}
380+
return domainId;
381+
}
382+
383+
@NotNull
384+
private Long getAccountIdFromDomainPlusName(Long domainId, String accountName, Account caller) {
385+
Long accountId;
386+
Account userAccount = null;
387+
if (! _domainDao.isChildDomain(caller.getDomainId(), domainId)) {
388+
throw new PermissionDeniedException("Invalid Domain Id or Account");
389+
}
390+
Filter filter = new Filter(AccountVO.class, "id", Boolean.FALSE, null, null);
391+
List<AccountVO> accounts = _accountDao.listAccounts(accountName, domainId, filter);
392+
if (accounts.size() > 0) {
393+
userAccount = accounts.get(0);
394+
}
395+
if (userAccount == null) {
396+
throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
397+
}
398+
return userAccount.getId();
399+
}
400+
401+
@NotNull
402+
private Long getAccountIdFromProject(Long projectId) {
403+
Long accountId;
404+
Project project = _projectMgr.getProject(projectId);
405+
if (project == null) {
406+
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
407+
}
408+
final long projectAccountId = project.getProjectAccountId();
409+
if (s_logger.isInfoEnabled()) {
410+
s_logger.info(String.format("Using projectAccountId %d for project %s [%s] as account id", projectAccountId, project.getName(), project.getUuid()));
411+
}
412+
accountId = projectAccountId;
413+
return accountId;
414+
}
415+
400416
private void checkUserAccess(ListUsageRecordsCmd cmd, Long accountId, Account caller, boolean isNormalUser) {
401417
if (isNormalUser) {
402418
// A user can only access their own account records

0 commit comments

Comments
 (0)