Skip to content

Commit 956efb2

Browse files
allow filtering of listDiskOffering and listServiceOffering APIs by account or project (#7082)
1 parent 8f39087 commit 956efb2

File tree

3 files changed

+24
-19
lines changed

3 files changed

+24
-19
lines changed

api/src/main/java/org/apache/cloudstack/api/command/user/offering/ListDiskOfferingsCmd.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,21 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.user.offering;
1818

19+
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
1920
import org.apache.cloudstack.api.response.StoragePoolResponse;
2021
import org.apache.cloudstack.api.response.VolumeResponse;
2122
import org.apache.cloudstack.api.response.ZoneResponse;
2223
import org.apache.log4j.Logger;
2324

2425
import org.apache.cloudstack.api.APICommand;
2526
import org.apache.cloudstack.api.ApiConstants;
26-
import org.apache.cloudstack.api.BaseListDomainResourcesCmd;
2727
import org.apache.cloudstack.api.Parameter;
2828
import org.apache.cloudstack.api.response.DiskOfferingResponse;
2929
import org.apache.cloudstack.api.response.ListResponse;
3030

3131
@APICommand(name = "listDiskOfferings", description = "Lists all available disk offerings.", responseObject = DiskOfferingResponse.class,
3232
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
33-
public class ListDiskOfferingsCmd extends BaseListDomainResourcesCmd {
33+
public class ListDiskOfferingsCmd extends BaseListProjectAndAccountResourcesCmd {
3434
public static final Logger s_logger = Logger.getLogger(ListDiskOfferingsCmd.class.getName());
3535

3636

api/src/main/java/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.user.offering;
1818

19+
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
1920
import org.apache.cloudstack.api.response.ZoneResponse;
2021
import org.apache.log4j.Logger;
2122

2223
import org.apache.cloudstack.api.APICommand;
2324
import org.apache.cloudstack.api.ApiConstants;
24-
import org.apache.cloudstack.api.BaseListDomainResourcesCmd;
2525
import org.apache.cloudstack.api.Parameter;
2626
import org.apache.cloudstack.api.response.ListResponse;
2727
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
2828
import org.apache.cloudstack.api.response.UserVmResponse;
2929

3030
@APICommand(name = "listServiceOfferings", description = "Lists all available service offerings.", responseObject = ServiceOfferingResponse.class,
3131
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
32-
public class ListServiceOfferingsCmd extends BaseListDomainResourcesCmd {
32+
public class ListServiceOfferingsCmd extends BaseListProjectAndAccountResourcesCmd {
3333
public static final Logger s_logger = Logger.getLogger(ListServiceOfferingsCmd.class.getName());
3434

3535

server/src/main/java/com/cloud/api/query/QueryManagerImpl.java

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2929,6 +2929,8 @@ private Pair<List<DiskOfferingJoinVO>, Integer> searchForDiskOfferingsInternal(L
29292929
Object id = cmd.getId();
29302930
Object keyword = cmd.getKeyword();
29312931
Long domainId = cmd.getDomainId();
2932+
Long projectId = cmd.getProjectId();
2933+
String accountName = cmd.getAccountName();
29322934
Boolean isRootAdmin = _accountMgr.isRootAdmin(account.getAccountId());
29332935
Boolean isRecursive = cmd.isRecursive();
29342936
Long zoneId = cmd.getZoneId();
@@ -2938,7 +2940,7 @@ private Pair<List<DiskOfferingJoinVO>, Integer> searchForDiskOfferingsInternal(L
29382940
// Keeping this logic consistent with domain specific zones
29392941
// if a domainId is provided, we just return the disk offering
29402942
// associated with this domain
2941-
if (domainId != null) {
2943+
if (domainId != null && accountName == null) {
29422944
if (_accountMgr.isRootAdmin(account.getId()) || isPermissible(account.getDomainId(), domainId)) {
29432945
// check if the user's domain == do's domain || user's domain is
29442946
// a child of so's domain for non-root users
@@ -3019,9 +3021,9 @@ private Pair<List<DiskOfferingJoinVO>, Integer> searchForDiskOfferingsInternal(L
30193021

30203022
// Filter offerings that are not associated with caller's domain
30213023
// Fetch the offering ids from the details table since theres no smart way to filter them in the join ... yet!
3022-
Account caller = CallContext.current().getCallingAccount();
3023-
if (caller.getType() != Account.Type.ADMIN) {
3024-
Domain callerDomain = _domainDao.findById(caller.getDomainId());
3024+
account = _accountMgr.finalizeOwner(account, accountName, domainId, projectId);
3025+
if (!Account.Type.ADMIN.equals(account.getType())) {
3026+
Domain callerDomain = _domainDao.findById(account.getDomainId());
30253027
List<Long> domainIds = findRelatedDomainIds(callerDomain, isRecursive);
30263028

30273029
List<Long> ids = _diskOfferingDetailsDao.findOfferingIdsByDomainIds(domainIds);
@@ -3100,6 +3102,8 @@ private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInte
31003102
searchFilter.addOrderBy(ServiceOfferingJoinVO.class, "id", true);
31013103

31023104
Account caller = CallContext.current().getCallingAccount();
3105+
Long projectId = cmd.getProjectId();
3106+
String accountName = cmd.getAccountName();
31033107
Object name = cmd.getServiceOfferingName();
31043108
Object id = cmd.getId();
31053109
Object keyword = cmd.getKeyword();
@@ -3115,9 +3119,10 @@ private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInte
31153119
Integer cpuSpeed = cmd.getCpuSpeed();
31163120
Boolean encryptRoot = cmd.getEncryptRoot();
31173121

3122+
final Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
31183123
SearchCriteria<ServiceOfferingJoinVO> sc = _srvOfferingJoinDao.createSearchCriteria();
31193124
if (!_accountMgr.isRootAdmin(caller.getId()) && isSystem) {
3120-
throw new InvalidParameterValueException("Only ROOT admins can access system's offering");
3125+
throw new InvalidParameterValueException("Only ROOT admins can access system offerings.");
31213126
}
31223127

31233128
// Keeping this logic consistent with domain specific zones
@@ -3126,8 +3131,8 @@ private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInte
31263131
if (domainId != null && !_accountMgr.isRootAdmin(caller.getId())) {
31273132
// check if the user's domain == so's domain || user's domain is a
31283133
// child of so's domain
3129-
if (!isPermissible(caller.getDomainId(), domainId)) {
3130-
throw new PermissionDeniedException("The account:" + caller.getAccountName() + " does not fall in the same domain hierarchy as the service offering");
3134+
if (!isPermissible(owner.getDomainId(), domainId)) {
3135+
throw new PermissionDeniedException("The account:" + owner.getAccountName() + " does not fall in the same domain hierarchy as the service offering");
31313136
}
31323137
}
31333138

@@ -3139,7 +3144,7 @@ private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInte
31393144
throw ex;
31403145
}
31413146

3142-
_accountMgr.checkAccess(caller, null, true, vmInstance);
3147+
_accountMgr.checkAccess(owner, null, true, vmInstance);
31433148

31443149
currentVmOffering = _srvOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
31453150
if (! currentVmOffering.isDynamic()) {
@@ -3187,22 +3192,22 @@ private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInte
31873192
}
31883193

31893194
// boolean includePublicOfferings = false;
3190-
if ((_accountMgr.isNormalUser(caller.getId()) || _accountMgr.isDomainAdmin(caller.getId())) || caller.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN) {
3195+
if ((_accountMgr.isNormalUser(owner.getId()) || _accountMgr.isDomainAdmin(owner.getId())) || owner.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN) {
31913196
// For non-root users.
31923197
if (isSystem) {
31933198
throw new InvalidParameterValueException("Only root admins can access system's offering");
31943199
}
31953200
if (isRecursive) { // domain + all sub-domains
3196-
if (caller.getType() == Account.Type.NORMAL) {
3201+
if (owner.getType() == Account.Type.NORMAL) {
31973202
throw new InvalidParameterValueException("Only ROOT admins and Domain admins can list service offerings with isrecursive=true");
31983203
}
31993204
}
32003205
} else {
32013206
// for root users
3202-
if (caller.getDomainId() != 1 && isSystem) { // NON ROOT admin
3203-
throw new InvalidParameterValueException("Non ROOT admins cannot access system's offering");
3207+
if (owner.getDomainId() != 1 && isSystem) { // NON ROOT admin
3208+
throw new InvalidParameterValueException("Non ROOT admins cannot access system's offering.");
32043209
}
3205-
if (domainId != null) {
3210+
if (domainId != null && accountName == null) {
32063211
sc.addAnd("domainId", Op.FIND_IN_SET, String.valueOf(domainId));
32073212
}
32083213
}
@@ -3286,8 +3291,8 @@ private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInte
32863291

32873292
// Filter offerings that are not associated with caller's domain
32883293
// Fetch the offering ids from the details table since theres no smart way to filter them in the join ... yet!
3289-
if (caller.getType() != Account.Type.ADMIN) {
3290-
Domain callerDomain = _domainDao.findById(caller.getDomainId());
3294+
if (owner.getType() != Account.Type.ADMIN) {
3295+
Domain callerDomain = _domainDao.findById(owner.getDomainId());
32913296
List<Long> domainIds = findRelatedDomainIds(callerDomain, isRecursive);
32923297

32933298
List<Long> ids = _srvOfferingDetailsDao.findOfferingIdsByDomainIds(domainIds);

0 commit comments

Comments
 (0)