/** * Licensed to the Austrian Association for Software Tool Integration (AASTI) * under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. The AASTI licenses this file to you 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. */ package org.openengsb.core.services.internal.security; import java.util.Iterator; import java.util.List; import org.openengsb.core.api.AliveState; import org.openengsb.core.api.OsgiUtilsService; import org.openengsb.core.common.AbstractDelegateStrategy; import org.openengsb.core.common.AbstractOpenEngSBConnectorService; import org.openengsb.domain.authorization.AuthorizationDomain; import org.openengsb.domain.authorization.AuthorizationDomain.Access; import org.osgi.framework.ServiceReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Composite strategy for {@link AuthorizationDomain}. * * On every associated connector the "supports" method is called to determine if they can handle the supplied object. * For a successful authorization at least one {@link Access#GRANTED} vote is required. The first {@link Access#DENIED} * vote causes the strategy to deny access too. If all connectors abstain, the strategy abstains too. */ public class AffirmativeBasedAuthorizationStrategy extends AbstractDelegateStrategy { private static final Logger LOGGER = LoggerFactory.getLogger(AffirmativeBasedAuthorizationStrategy.class); private OsgiUtilsService utilsService; private static class CompositeAccessControlProvider extends AbstractOpenEngSBConnectorService implements AuthorizationDomain { private List<ServiceReference> providers; private OsgiUtilsService utilsService; public CompositeAccessControlProvider(List<ServiceReference> providers, OsgiUtilsService utilsService) { this.providers = providers; this.utilsService = utilsService; } @Override public Access checkAccess(final String user, Object action) { Iterator<AuthorizationDomain> serviceIterator = utilsService.getServiceIterator(providers, AuthorizationDomain.class); LOGGER.debug("iterating {} authenticationProviderServices", providers.size()); boolean granted = false; while (serviceIterator.hasNext()) { AuthorizationDomain provider = serviceIterator.next(); Access checkAccess = provider.checkAccess(user, action); if (checkAccess == Access.GRANTED) { granted = true; } else if (checkAccess == Access.DENIED) { return Access.DENIED; } } return granted ? Access.GRANTED : Access.ABSTAINED; } @Override public AliveState getAliveState() { return AliveState.ONLINE; } } @Override protected Object createDelegate(List<ServiceReference> services) { return new CompositeAccessControlProvider(services, utilsService); } @Override public boolean supports(Class<?> domainClass) { return AuthorizationDomain.class.isAssignableFrom(domainClass); } public void setUtilsService(OsgiUtilsService utilsService) { this.utilsService = utilsService; } }