diff --git a/engine/components-api/src/com/cloud/template/TemplateManager.java b/engine/components-api/src/com/cloud/template/TemplateManager.java index 0a07f6b4a3d..7cb53cf61d9 100755 --- a/engine/components-api/src/com/cloud/template/TemplateManager.java +++ b/engine/components-api/src/com/cloud/template/TemplateManager.java @@ -113,4 +113,5 @@ public interface TemplateManager { TemplateInfo prepareIso(long isoId, long dcId); + public static final String MESSAGE_REGISTER_PUBLIC_TEMPLATE_EVENT = "Message.RegisterPublicTemplate.Event"; } diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 25e79db2bbe..deda42aa387 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -44,6 +44,8 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcContext; +import org.apache.cloudstack.framework.messagebus.MessageBus; +import org.apache.cloudstack.framework.messagebus.PublishScope; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; @@ -95,6 +97,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { EndPointSelector _epSelector; @Inject DataCenterDao _dcDao; + @Inject + MessageBus _messageBus; @Override public String getName() { @@ -267,6 +271,10 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { TemplateInfo template = context.template; if (result.isSuccess()) { VMTemplateVO tmplt = _tmpltDao.findById(template.getId()); + // need to grant permission for public templates + if (tmplt.isPublicTemplate()) { + _messageBus.publish(_name, TemplateManager.MESSAGE_REGISTER_PUBLIC_TEMPLATE_EVENT, PublishScope.LOCAL, tmplt.getId()); + } long accountId = tmplt.getAccountId(); if (template.getSize() != null) { // publish usage event diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedAPIAccessChecker.java b/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedAPIAccessChecker.java index fc39e102613..5a322987140 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedAPIAccessChecker.java +++ b/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedAPIAccessChecker.java @@ -40,6 +40,8 @@ import org.apache.cloudstack.iam.api.IAMService; import com.cloud.api.ApiServerService; import com.cloud.exception.PermissionDeniedException; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.dao.VMTemplateDao; import com.cloud.user.Account; import com.cloud.user.AccountService; import com.cloud.user.User; @@ -61,6 +63,8 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker ApiServerService _apiServer; @Inject IAMService _iamSrv; + @Inject + VMTemplateDao _templateDao; Set commandsPropertiesOverrides = new HashSet(); Map> commandsPropertiesRoleBasedApisMap = new HashMap>(); @@ -122,6 +126,15 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN + 1), null, null, null, "DomainResourceCapability", null, Permission.Allow); + // add permissions for public templates + List pTmplts = _templateDao.listByPublic(); + for (VMTemplateVO tmpl : pTmplts){ + _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), AclEntityType.VirtualMachineTemplate.toString(), + PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow); + _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), AclEntityType.VirtualMachineTemplate.toString(), + PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow); + } + for (PluggableService service : _services) { for (Class cmdClass : service.getCommands()) { APICommand command = cmdClass.getAnnotation(APICommand.class); diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java index d50f4f2aa11..35f7d96d691 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java +++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java @@ -65,6 +65,7 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; @@ -150,6 +151,20 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man } }); + _messageBus.subscribe(TemplateManager.MESSAGE_REGISTER_PUBLIC_TEMPLATE_EVENT, new MessageSubscriber() { + @Override + public void onPublishMessage(String senderAddress, String subject, Object obj) { + Long templateId = (Long)obj; + if (templateId != null) { + s_logger.debug("MessageBus message: new public template registered: " + templateId + ", grant permission to domain admin and normal user policies"); + _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), AclEntityType.VirtualMachineTemplate.toString(), + PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow); + _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), AclEntityType.VirtualMachineTemplate.toString(), + PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow); + } + } + }); + return super.configure(name, params); }