JmxPermission.java
package com.ziesemer.utils.jmx.server.authorization;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.HashSet;
import java.util.Set;
/**
* <p>An alternative to {@link javax.management.MBeanPermission}, used by
* {@link JmxPermissionPrincipal} to provide a concept of JMX roles
* around the individual "permissions" otherwise exposed by
* {@link javax.management.MBeanPermission}.</p>
* <p>Should typically be used with {@link JmxPermissionAuthorizer}.
* Can also be used directly with
* {@link javax.security.auth.Subject#getSubject(java.security.AccessControlContext)}
* and {@link java.security.AccessController#getContext()}, without the need for
* a specific {@link SecurityManager}.
* See also: {@link JmxPermissionPrincipal#getCurrent()}.</p>
* <p>A common set of roles (permissions) are defined as singletons on this class.
* Additional and/or alternate subclasses may be created and used,
* but should also be kept as singletons.</p>
* @author Mark A. Ziesemer
* <a href="http://www.ziesemer.com."><www.ziesemer.com></a>
*/
public abstract class JmxPermission extends Permission{
private static final long serialVersionUID = 1L;
protected final Set<JmxPermission> implies = new HashSet<JmxPermission>();
/**
* <p>Required for performing any JMX operation.
* Allows reading of any attributes and invocation of any "read-only" operations.
* Will typically include invocation of any operation marked with
* {@link javax.management.MBeanOperationInfo#INFO}, or allowed by {@link ReadOnlyInvokeHandler}.</p>
*/
public static final JmxPermission CONNECT = new ConnectPermission();
private static final class ConnectPermission extends JmxPermission{
private static final long serialVersionUID = 1L;
protected ConnectPermission(){
super("Connect");
}
}
/**
* <p>Required for performing "extended" read-only operations,
* including those that may be computationally expensive.
* Includes {@link #CONNECT}.</p>
*/
public static final JmxPermission READ_EX = new ReadExPermission();
private static final class ReadExPermission extends JmxPermission{
private static final long serialVersionUID = 1L;
protected ReadExPermission(){
super("Read extended", CONNECT);
}
}
/**
* <p>Required for setting most attributes and invocation of most methods
* not already covered by {@link #READ_EX}.
* Will typically include invocation of any operation marked with
* {@link javax.management.MBeanOperationInfo#ACTION} or
* {@link javax.management.MBeanOperationInfo#ACTION_INFO}.
* Includes {@link #READ_EX}.</p>
*/
public static final JmxPermission INVOKE = new InvokePermission();
private static final class InvokePermission extends JmxPermission{
private static final long serialVersionUID = 1L;
protected InvokePermission(){
super("Invoke", READ_EX);
}
}
/**
* <p>Allows all actions included by any other {@link JmxPermission},
* including those that may have more significant impact than allowed by {@link #INVOKE}.
* No other role (permission) should exist that includes more rights.</p>
*/
public static final JmxPermission ADMIN = new AdminPermission();
private static final class AdminPermission extends JmxPermission{
private static final long serialVersionUID = 1L;
protected AdminPermission(){
super("Admin");
}
@Override
public boolean implies(final Permission permission){
return permission instanceof JmxPermission;
}
}
protected JmxPermission(final String name, final JmxPermission... implies){
super(name);
this.implies.add(this);
for(final JmxPermission p : implies){
initImplies(p);
}
}
private void initImplies(final JmxPermission p){
if(implies.add(p)){
for(final JmxPermission cp : p.implies){
initImplies(cp);
}
}
}
@Override
public String getActions(){
return null;
}
@Override
public boolean implies(final Permission permission){
return implies.contains(permission);
}
@Override
public PermissionCollection newPermissionCollection(){
return new JmxPermissions();
}
@Override
public boolean equals(final Object obj){
if(obj == null){
return false;
}
return getClass().equals(obj.getClass());
}
@Override
public int hashCode(){
return getClass().hashCode();
}
}