package org.jolokia.osgi.security; import javax.management.ObjectName; import org.jolokia.restrictor.Restrictor; import org.jolokia.util.HttpMethod; import org.jolokia.util.RequestType; import org.osgi.framework.*; /* * Copyright 2009-2013 Roland Huss * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * A restrictor which delegate to a RestrictorService if available or denies access * if none is available. If multiple services are available, it will grant access * only if all restrictors allow */ public class DelegatingRestrictor implements Restrictor { private BundleContext bundleContext; /** * Constructor remembering the bundle context * * @param pBundleContext bundle context to remember */ public DelegatingRestrictor(BundleContext pBundleContext) { bundleContext = pBundleContext; } /** * Actual check which delegate to one or more restrictor services if available. * * @param pCheck a function object for performing the actual check * @param args arguments passed through to the check * @return true if all checks return true */ private boolean checkRestrictorService(RestrictorCheck pCheck, Object ... args) { try { ServiceReference[] serviceRefs = bundleContext.getServiceReferences(Restrictor.class.getName(),null); if (serviceRefs != null) { boolean ret = true; boolean found = false; for (ServiceReference serviceRef : serviceRefs) { Restrictor restrictor = (Restrictor) bundleContext.getService(serviceRef); if (restrictor != null) { ret = ret && pCheck.check(restrictor,args); found = true; } } return found && ret; } else { return false; } } catch (InvalidSyntaxException e) { // Will not happen, since we dont use a filter here throw new IllegalArgumentException("Impossible exception (we don't use a filter for fetching the services)",e); } } // ==================================================================== private static final RestrictorCheck HTTP_METHOD_CHECK = new RestrictorCheck() { /** {@inheritDoc} */ public boolean check(Restrictor restrictor,Object ... args) { return restrictor.isHttpMethodAllowed((HttpMethod) args[0]); } }; /** {@inheritDoc} */ public boolean isHttpMethodAllowed(HttpMethod pMethod) { return checkRestrictorService(HTTP_METHOD_CHECK,pMethod); } // ==================================================================== private static final RestrictorCheck TYPE_CHECK = new RestrictorCheck() { /** {@inheritDoc} */ public boolean check(Restrictor restrictor,Object ... args) { return restrictor.isTypeAllowed((RequestType) args[0]); } }; /** {@inheritDoc} */ public boolean isTypeAllowed(RequestType pType) { return checkRestrictorService(TYPE_CHECK, pType); } // ==================================================================== private static final RestrictorCheck ATTRIBUTE_READ_CHECK = new RestrictorCheck() { /** {@inheritDoc} */ public boolean check(Restrictor restrictor,Object ... args) { return restrictor.isAttributeReadAllowed((ObjectName) args[0], (String) args[1]); } }; /** {@inheritDoc} */ public boolean isAttributeReadAllowed(ObjectName pName, String pAttribute) { return checkRestrictorService(ATTRIBUTE_READ_CHECK,pName,pAttribute); } // ==================================================================== private static final RestrictorCheck ATTRIBUTE_WRITE_CHECK = new RestrictorCheck() { /** {@inheritDoc} */ public boolean check(Restrictor restrictor,Object ... args) { return restrictor.isAttributeWriteAllowed((ObjectName) args[0], (String) args[1]); } }; /** {@inheritDoc} */ public boolean isAttributeWriteAllowed(ObjectName pName, String pAttribute) { return checkRestrictorService(ATTRIBUTE_WRITE_CHECK,pName,pAttribute); } // ==================================================================== private static final RestrictorCheck OPERATION_CHECK = new RestrictorCheck() { /** {@inheritDoc} */ public boolean check(Restrictor restrictor,Object ... args) { return restrictor.isOperationAllowed((ObjectName) args[0], (String) args[1]); } }; /** {@inheritDoc} */ public boolean isOperationAllowed(ObjectName pName, String pOperation) { return checkRestrictorService(OPERATION_CHECK,pName,pOperation); } // ==================================================================== private static final RestrictorCheck REMOTE_CHECK = new RestrictorCheck() { /** {@inheritDoc} */ public boolean check(Restrictor restrictor,Object ... args) { String[] argsS = new String[args.length]; for (int i = 0; i < args.length; i++) { argsS[i] = (String) args[i]; } return restrictor.isRemoteAccessAllowed(argsS); } }; /** {@inheritDoc} */ public boolean isRemoteAccessAllowed(String... pHostOrAddress) { return checkRestrictorService(REMOTE_CHECK,pHostOrAddress); } // ==================================================================== private static final RestrictorCheck CORS_CHECK = new RestrictorCheck() { /** {@inheritDoc} */ public boolean check(Restrictor restrictor, Object... args) { return restrictor.isOriginAllowed((String) args[0], (Boolean) args[1]); } }; /** {@inheritDoc} */ public boolean isOriginAllowed(String pOrigin, boolean pIsStrictCheck) { return checkRestrictorService(CORS_CHECK,pOrigin,pIsStrictCheck); } // ======================================================================================================= /** * Internal interface for restrictor delegation */ private interface RestrictorCheck { /** * Run check specifically for the restrictor to delegate to * @param restrictor the restrictor on which the check should be run * @param args context dependent arguments * @return result of the check */ boolean check(Restrictor restrictor,Object ... args); } }