/**
* NOTE: This copyright does *not* cover user programs that use HQ
* program services by normal system calls through the application
* program interfaces provided as part of the Hyperic Plug-in Development
* Kit or the Hyperic Client Development Kit - this is merely considered
* normal use of the program, and does *not* fall under the heading of
* "derived work".
*
* Copyright (C) [2009-2010], VMware, Inc.
* This file is part of HQ.
*
* HQ is free software; you can redistribute it and/or modify
* it under the terms version 2 of the GNU General Public License as
* published by the Free Software Foundation. This program is distributed
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
*/
package org.hyperic.hq.events;
import java.util.HashMap;
import java.util.Map;
import org.hyperic.hq.appdef.shared.AppdefEntityConstants;
import org.hyperic.hq.appdef.shared.AppdefEntityID;
import org.hyperic.hq.appdef.shared.AppdefEntityTypeID;
import org.hyperic.hq.appdef.shared.AppdefUtil;
import org.hyperic.hq.appdef.shared.InvalidAppdefTypeException;
import org.hyperic.hq.authz.server.session.AuthzSubject;
import org.hyperic.hq.authz.server.session.Operation;
import org.hyperic.hq.authz.server.session.OperationDAO;
import org.hyperic.hq.authz.server.session.ResourceType;
import org.hyperic.hq.authz.server.session.ResourceTypeDAO;
import org.hyperic.hq.authz.shared.AuthzConstants;
import org.hyperic.hq.authz.shared.PermissionException;
import org.hyperic.hq.authz.shared.PermissionManager;
import org.hyperic.hq.authz.shared.PermissionManagerFactory;
import org.hyperic.hq.authz.shared.ResourceOperationsHelper;
import org.hyperic.hq.authz.shared.RoleManager;
import org.hyperic.hq.events.server.session.AlertDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class DefaultAlertPermissionManager implements AlertPermissionManager {
/**
* Check the permission based on resource type, instance ID, and operation
* @param subjectId the subject trying to perform the operation
* @param rtName the resource type name
* @param instId the instance ID
* @param operation the operation
* @throws PermissionException if the user is not authorized to perform the
* operation on the resource
*/
private Map resourceTypes = new HashMap();
private Map operations = new HashMap();
private OperationDAO operationDAO;
private ResourceTypeDAO resourceTypeDAO;
private RoleManager roleManager;
@Autowired
public DefaultAlertPermissionManager(OperationDAO operationDAO, ResourceTypeDAO resourceTypeDAO, RoleManager roleManager) {
this.operationDAO = operationDAO;
this.resourceTypeDAO = resourceTypeDAO;
this.roleManager = roleManager;
}
private void checkPermission(Integer subjectId, String rtName, Integer instId, String opName) throws PermissionException
{
// ...check permission if user is NOT a super user...
if (!PermissionManagerFactory.getInstance().hasAdminPermission(subjectId)) {
PermissionManager permMgr = PermissionManagerFactory.getInstance();
if (!resourceTypes.containsKey(rtName)) {
resourceTypes.put(rtName, resourceTypeDAO.findByName(rtName));
}
ResourceType resType = (ResourceType) resourceTypes.get(rtName);
if (!operations.containsKey(opName)) {
operations.put(opName,operationDAO.findByTypeAndName(resType, opName));
}
Operation operation = (Operation) operations.get(opName);
permMgr.check(subjectId, resType.getId(), instId, operation.getId());
// Permission Check Succesful
}
}
public void canViewResourceTypeAlertDefinitionTemplate(AuthzSubject user)
throws PermissionException {
// ...right now, you have to be a member of the super user's role to do anything with
// resource type alert templates...
// TODO ...if this changes in the future, we can make the change here and the rest should just work...
if (!PermissionManagerFactory.getInstance().hasAdminPermission(user.getId())) {
throw new PermissionException("User must be in Super User role to manage resource type alert definitions");
}
}
public void canModifyResourceTypeAlertDefinitionTemplate(AuthzSubject user)
throws PermissionException {
// ...right now, you have to be a member of the super user's role to do anything with
// resource type alert templates...
// TODO ...if this changes in the future, we can make the change here and the rest should just work...
if (!PermissionManagerFactory.getInstance().hasAdminPermission(user.getId())) {
throw new PermissionException("User must be in Super User role to manage resource type alert definitions");
}
}
public void canCreateResourceTypeAlertDefinitionTemplate(AuthzSubject user)
throws PermissionException {
// ...right now, you have to be a member of the super user's role to do anything with
// resource type alert templates...
// TODO ...if this changes in the future, we can make the change here and the rest should just work...
if (!PermissionManagerFactory.getInstance().hasAdminPermission(user.getId())) {
throw new PermissionException("User must be in Super User role to manage resource type alert definitions");
}
}
public void canDeleteResourceTypeAlertDefinitionTemplate(AuthzSubject user)
throws PermissionException {
// ...right now, you have to be a member of the super user's role to do anything with
// resource type alert templates...
// TODO ...if this changes in the future, we can make the change here and the rest should just work...
if (!PermissionManagerFactory.getInstance().hasAdminPermission(user.getId())) {
throw new PermissionException("User must be in Super User role to manage resource type alert definitions");
}
}
public void canViewAlertDefinition(AuthzSubject user, AppdefEntityID entityId)
throws PermissionException {
// ...we need to check the resource associated with the alert definition to determine
// if the user can view the alert definition. Must have read permission on resource...
checkAlertDefinitionPermission(user, entityId, ResourceOperationsHelper.getReadOperation(entityId.getType()));
}
public void canModifyAlertDefinition(AuthzSubject user, AppdefEntityID entityId)
throws PermissionException {
// ...we need to check the resource associated with the alert definition to determine
// if the user can modify the alert definition. Must have modify permission on resource...
checkAlertDefinitionPermission(user, entityId, ResourceOperationsHelper.getUpdateOperation(entityId.getType()));
}
public void canCreateAlertDefinition(AuthzSubject user, AppdefEntityID entityId)
throws PermissionException {
// ...we need to check the resource associated with the alert definition to determine
// if the user can modify the alert definition. Must have modify permission on resource...
// TODO ...If we introduce finer grained permission for Alert definition, we can make the change here
// and the rest should just work...
checkAlertDefinitionPermission(user, entityId, ResourceOperationsHelper.getUpdateOperation(entityId.getType()));
}
public void canDeleteAlertDefinition(AuthzSubject user, AppdefEntityID entityId)
throws PermissionException {
// ...we need to check the resource associated with the alert definition to determine
// if the user can modify the alert definition. Must have modify permission on resource...
// TODO ...If we introduce finer grained permission for Alert definition, we can make the change here
// and the rest should just work...
checkAlertDefinitionPermission(user, entityId, ResourceOperationsHelper.getUpdateOperation(entityId.getType()));
}
private void checkAlertDefinitionPermission(AuthzSubject user, AppdefEntityID id, String operationName)
throws PermissionException {
if (user.getId().equals(AuthzConstants.overlordId)) {
return;
}
int resourceType = id.getType();
String resourceTypeLabel;
switch (resourceType) {
case AppdefEntityConstants.APPDEF_TYPE_PLATFORM:
resourceTypeLabel = AuthzConstants.platformResType;
break;
case AppdefEntityConstants.APPDEF_TYPE_SERVER:
resourceTypeLabel = AuthzConstants.serverResType;
break;
case AppdefEntityConstants.APPDEF_TYPE_SERVICE:
resourceTypeLabel = AuthzConstants.serviceResType;
break;
case AppdefEntityConstants.APPDEF_TYPE_GROUP:
resourceTypeLabel = AuthzConstants.groupResType;
break;
default:
throw new PermissionException("Unknown type: " + resourceType);
}
// ...check based on resource type to see if we have the requested permission...
checkPermission(user.getId(), resourceTypeLabel, id.getId(), operationName);
}
public void canFixAcknowledgeAlerts(AuthzSubject who, AlertDefinitionInterface adi)
throws PermissionException {
if (adi.isDeleted()) { // Don't need to check deleted alert defs
return;
}
Integer parentId = null;
if (adi instanceof AlertDefinition) {
AlertDefinition ad = (AlertDefinition) adi;
parentId = ad.getParent() != null ? ad.getParent().getId() : null;
}
if (!EventConstants.TYPE_ALERT_DEF_ID.equals(parentId)) {
canFixAcknowledgeAlerts(who, AppdefUtil.newAppdefEntityId(adi.getResource()));
}
}
/**
* Check for manage alerts permission for a given resource
*
* By manage, we mean the ability to fix/acknowledge alerts & pause escalations...
*/
public void canFixAcknowledgeAlerts(AuthzSubject user, AppdefEntityID entityId)
throws PermissionException {
try {
canModifyAlertDefinition(user, entityId);
} catch(PermissionException e) {
// ...first check that we can view the alert...
canViewAlertDefinition(user, entityId);
int resourceTypeId = entityId.getType();
// ...then check if we have fix/acknowledge permissions on alert...
checkPermission(user.getId(),
ResourceOperationsHelper.getResourceType(resourceTypeId),
entityId.getId(),
ResourceOperationsHelper.getManageAlertOperation(resourceTypeId));
}
}
public AppdefEntityID getAppdefEntityID(AlertDefinitionInterface adi) {
try {
return AppdefUtil.newAppdefEntityId(adi.getResource());
} catch (IllegalArgumentException e) {
if (adi instanceof AlertDefinition) {
AlertDefinition ad = (AlertDefinition) adi;
return new AppdefEntityTypeID(ad.getAppdefType(), ad.getAppdefId());
} else {
throw e;
}
}
}
private void checkEscalation(Integer subjectId,
String operation)
throws PermissionException {
// The escalation resource type is looked up for its ID to be used
// instance ID. The reason is that escalations are global, and we're
// not applying escalation permission per appdef resource.
ResourceType rt = resourceTypeDAO
.findByName(AuthzConstants.escalationResourceTypeName);
checkPermission(subjectId, AuthzConstants.rootResType, rt.getId(),
operation);
}
public void canCreateEscalation(Integer subjectId)
throws PermissionException {
checkEscalation(subjectId, AuthzConstants.escOpCreateEscalation);
}
public void canViewEscalation(Integer subjectId)
throws PermissionException {
checkEscalation(subjectId, AuthzConstants.escOpViewEscalation);
}
public void canModifyEscalation(Integer subjectId)
throws PermissionException {
checkEscalation(subjectId, AuthzConstants.escOpModifyEscalation);
}
public void canRemoveEscalation(Integer subjectId)
throws PermissionException {
checkEscalation(subjectId, AuthzConstants.escOpRemoveEscalation);
}
}