Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ public List<String> getAccountNames() {
if (accountNames != null && projectIds != null) {
throw new InvalidParameterValueException("Accounts and projectIds can't be specified together");
}

return accountNames;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public void execute() {
response.setKVMSnapshotEnabled((Boolean)capabilities.get("KVMSnapshotEnabled"));
response.setAllowUserViewDestroyedVM((Boolean)capabilities.get("allowUserViewDestroyedVM"));
response.setAllowUserExpungeRecoverVM((Boolean)capabilities.get("allowUserExpungeRecoverVM"));
response.setAllowUserViewAllDomainAccounts((Boolean)capabilities.get("allowUserViewAllDomainAccounts"));
if (capabilities.containsKey("apiLimitInterval")) {
response.setApiLimitInterval((Integer)capabilities.get("apiLimitInterval"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ public class CapabilitiesResponse extends BaseResponse {
@Param(description = "true if the user can recover and expunge virtualmachines, false otherwise", since = "4.6.0")
private boolean allowUserExpungeRecoverVM;

@SerializedName("allowuserviewalldomainaccounts")
@Param(description = "true if users can see all accounts within the same domain, false otherwise")
private boolean allowUserViewAllDomainAccounts;

public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
this.securityGroupsEnabled = securityGroupsEnabled;
}
Expand Down Expand Up @@ -143,4 +147,8 @@ public void setAllowUserViewDestroyedVM(boolean allowUserViewDestroyedVM) {
public void setAllowUserExpungeRecoverVM(boolean allowUserExpungeRecoverVM) {
this.allowUserExpungeRecoverVM = allowUserExpungeRecoverVM;
}

public void setAllowUserViewAllDomainAccounts(boolean allowUserViewAllDomainAccounts) {
this.allowUserViewAllDomainAccounts = allowUserViewAllDomainAccounts;
}
}
15 changes: 13 additions & 2 deletions server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
* com.cloud.api.query.QueryService#searchForUsers(org.apache.cloudstack
* .api.command.admin.user.ListUsersCmd)
*/

public static final ConfigKey<Boolean> allowUserViewAllDomainAccounts = new ConfigKey<>("Advanced", Boolean.class,
"allow.user.view.all.domain.accounts", "false", "Determines whether users can view all user accounts within the same domain", true, ConfigKey.Scope.Domain);
@Override
public ListResponse<UserResponse> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException {
Pair<List<UserAccountJoinVO>, Integer> result = searchForUsersInternal(cmd);
Expand Down Expand Up @@ -1963,7 +1966,8 @@ private Pair<List<AccountJoinVO>, Integer> searchForAccountsInternal(ListAccount
// if no "id" specified...
if (accountId == null) {
// listall only has significance if they are an admin
if (listAll && callerIsAdmin) {
boolean isDomainListAllAllowed = allowUserViewAllDomainAccounts.valueIn(caller.getDomainId());
if ((listAll && callerIsAdmin) || isDomainListAllAllowed) {
// if no domain id specified, use caller's domain
if (domainId == null) {
domainId = caller.getDomainId();
Expand Down Expand Up @@ -2009,6 +2013,7 @@ private Pair<List<AccountJoinVO>, Integer> searchForAccountsInternal(ListAccount
sb.and("needsCleanup", sb.entity().isNeedsCleanup(), SearchCriteria.Op.EQ);
sb.and("typeNEQ", sb.entity().getType(), SearchCriteria.Op.NEQ);
sb.and("idNEQ", sb.entity().getId(), SearchCriteria.Op.NEQ);
sb.and("type2NEQ", sb.entity().getType(), SearchCriteria.Op.NEQ);

if (domainId != null && isRecursive) {
sb.and("path", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
Expand All @@ -2018,9 +2023,15 @@ private Pair<List<AccountJoinVO>, Integer> searchForAccountsInternal(ListAccount

// don't return account of type project to the end user
sc.setParameters("typeNEQ", Account.ACCOUNT_TYPE_PROJECT);

// don't return system account...
sc.setParameters("idNEQ", Account.ACCOUNT_ID_SYSTEM);

// do not return account of type domain admin to the end user
if (!callerIsAdmin) {
sc.setParameters("type2NEQ", Account.ACCOUNT_TYPE_DOMAIN_ADMIN);
}

if (keyword != null) {
SearchCriteria<AccountJoinVO> ssc = _accountJoinDao.createSearchCriteria();
ssc.addOr("accountName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
Expand Down Expand Up @@ -3714,6 +3725,6 @@ public String getConfigComponentName() {

@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {AllowUserViewDestroyedVM};
return new ConfigKey<?>[] {AllowUserViewDestroyedVM, allowUserViewAllDomainAccounts};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3455,6 +3455,8 @@ public Map<String, Object> listCapabilities(final ListCapabilitiesCmd cmd) {
final boolean allowUserViewDestroyedVM = (QueryManagerImpl.AllowUserViewDestroyedVM.valueIn(caller.getId()) | _accountService.isAdmin(caller.getId()));
final boolean allowUserExpungeRecoverVM = (UserVmManager.AllowUserExpungeRecoverVm.valueIn(caller.getId()) | _accountService.isAdmin(caller.getId()));

final boolean allowUserViewAllDomainAccounts = (QueryManagerImpl.allowUserViewAllDomainAccounts.valueIn(caller.getDomainId()));

// check if region-wide secondary storage is used
boolean regionSecondaryEnabled = false;
final List<ImageStoreVO> imgStores = _imgStoreDao.findRegionImageStores();
Expand All @@ -3474,6 +3476,7 @@ public Map<String, Object> listCapabilities(final ListCapabilitiesCmd cmd) {
capabilities.put("KVMSnapshotEnabled", KVMSnapshotEnabled);
capabilities.put("allowUserViewDestroyedVM", allowUserViewDestroyedVM);
capabilities.put("allowUserExpungeRecoverVM", allowUserExpungeRecoverVM);
capabilities.put("allowUserViewAllDomainAccounts", allowUserViewAllDomainAccounts);
if (apiLimitEnabled) {
capabilities.put("apiLimitInterval", apiLimitInterval);
capabilities.put("apiLimitMax", apiLimitMax);
Expand Down
8 changes: 8 additions & 0 deletions ui/css/cloudstack3.css
Original file line number Diff line number Diff line change
Expand Up @@ -12745,6 +12745,14 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
background-position: -35px -707px;
}

.shareTemplate .icon {
background-position: -165px -122px;
}

.shareTemplate .icon {
background-position: -165px -704px;
}

.createVolume .icon {
background-position: -70px -124px;
}
Expand Down
4 changes: 4 additions & 0 deletions ui/l10n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ var dictionary = {
"label.about.app":"About CloudStack",
"label.accept.project.invitation":"Accept project invitation",
"label.account":"Account",
"label.accounts":"Accounts",
"label.account.and.security.group":"Account, Security group",
"label.account.details":"Account details",
"label.account.id":"Account ID",
Expand Down Expand Up @@ -279,6 +280,7 @@ var dictionary = {
"label.action.run.diagnostics":"Run Diagnostics",
"label.action.secure.host":"Provision Host Security Keys",
"label.action.start.instance":"Start Instance",
"label.action.share.template": "Update Template Permissions",
"label.action.start.instance.processing":"Starting Instance....",
"label.action.start.router":"Start Router",
"label.action.start.router.processing":"Starting Router....",
Expand Down Expand Up @@ -1240,6 +1242,7 @@ var dictionary = {
"label.opendaylight.controller":"OpenDaylight Controller",
"label.opendaylight.controllerdetail":"OpenDaylight Controller Details",
"label.opendaylight.controllers":"OpenDaylight Controllers",
"label.operation": "Operation",
"label.operator":"Operator",
"label.optional":"Optional",
"label.order":"Order",
Expand Down Expand Up @@ -1329,6 +1332,7 @@ var dictionary = {
"label.project":"Project",
"label.project.dashboard":"Project dashboard",
"label.project.id":"Project ID",
"label.project.ids":"Project IDs",
"label.project.invite":"Invite to project",
"label.project.name":"Project name",
"label.project.view":"Project View",
Expand Down
2 changes: 2 additions & 0 deletions ui/scripts/cloudStack.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@
g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects;

g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion;
// Allow users to see all accounts within a domain
g_allowUserViewAllDomainAccounts = json.listcapabilitiesresponse.capability.allowuserviewalldomainaccounts;

if (json.listcapabilitiesresponse.capability.apilimitinterval != null && json.listcapabilitiesresponse.capability.apilimitmax != null) {
var intervalLimit = ((json.listcapabilitiesresponse.capability.apilimitinterval * 1000) / json.listcapabilitiesresponse.capability.apilimitmax) * 3; //multiply 3 to be on safe side
Expand Down
17 changes: 16 additions & 1 deletion ui/scripts/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1355,5 +1355,20 @@ cloudStack.docs = {
helpL2UserData: {
desc: 'Pass user and meta data to VMs (via ConfigDrive)',
externalLink: ''
}
},

// Update Template Permissions Helper
helpUpdateTemplateOperation: {
desc: 'Select the permission operator. Add is for sharing with user/project and Reset simply removes all the accounts and projects which template has been shared with.'
},
helpUpdateTemplateAccounts: {
desc: 'Choose one or more accounts to share this template. Ctrl+Click to select multiple accounts to share with. Accounts is mutually exclusive with Projects and only one of the 2 can be specified, do not select any projects when sharing templates with accounts.'
},
helpUpdateTemplateProjectIds: {
desc: 'Choose one or more projects to share this template. Ctrl+Click to select multiple projects to share with. Projects is mutually exclusive with Accounts and only one of the 2 can be specified, do not select any accounts when sharing templates with projects.'
},

helpUpdateTemplateAccountList: {
desc: 'A comma seperated list of accounts to share the template with. Must be specified with the Add/Remove operation, leave Project ID blank if this is specified.'
},
};
1 change: 1 addition & 0 deletions ui/scripts/sharedFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var g_cloudstackversion = null;
var g_queryAsyncJobResultInterval = 3000;
var g_idpList = null;
var g_appendIdpDomain = false;
var g_allowUserViewAllDomainAccounts= "false";

//keyboard keycode
var keycode_Enter = 13;
Expand Down
Loading