/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma.security; import java.util.Set; import javax.annotation.Nullable; import org.obiba.magma.Datasource; import org.obiba.magma.DatasourceFactory; import org.obiba.magma.DatasourceRegistry; import org.obiba.magma.Decorator; import org.obiba.magma.NoSuchDatasourceException; import org.obiba.magma.security.permissions.Permissions; import org.obiba.magma.support.Decorators; import org.obiba.magma.support.ValueTableReference; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; public class SecuredDatasourceRegistry implements DatasourceRegistry { private final Authorizer authorizer; private final DatasourceRegistry delegate; private final SecuredDatasourceDecorator securedDatasourceDecorator; public SecuredDatasourceRegistry(Authorizer authorizer, DatasourceRegistry datasourceRegistry) { if(authorizer == null) throw new IllegalArgumentException("authorizer cannot be null"); if(datasourceRegistry == null) throw new IllegalArgumentException("datasourceRegistry cannot be null"); this.authorizer = authorizer; delegate = datasourceRegistry; securedDatasourceDecorator = new SecuredDatasourceDecorator(authorizer); } @Override public ValueTableReference createReference(String reference) { return new SudoValueTableReference(authorizer, reference); } @Override public Datasource addDatasource(Datasource datasource) { return delegate.addDatasource(datasource); } @Override public Datasource addDatasource(DatasourceFactory factory) { return delegate.addDatasource(factory); } @Override public void addDecorator(Decorator<Datasource> decorator) { delegate.addDecorator(decorator); } @Override public String addTransientDatasource(DatasourceFactory factory) { return delegate.addTransientDatasource(factory); } @Override public Datasource getDatasource(String name) throws NoSuchDatasourceException { Datasource ds = delegate.getDatasource(name); if(ds != null && !isPermitted(Permissions.DatasourcePermissionBuilder.forDatasource(name).read().build())) throw new NoSuchDatasourceException(name); return securedDatasourceDecorator.decorate(ds); } @Override public Set<Datasource> getDatasources() { return ImmutableSet.copyOf(Iterables.transform(Sets.filter(delegate.getDatasources(), Permissions.DatasourcePermissionBuilder.forDatasource().read().asPredicate(authorizer)), Decorators.decoratingFunction(securedDatasourceDecorator))); } @Override public Datasource getTransientDatasourceInstance(String uid) { return delegate.getTransientDatasourceInstance(uid); } @Override public boolean hasDatasource(String name) { return delegate.hasDatasource(name) && isPermitted(Permissions.DatasourcePermissionBuilder.forDatasource(name).read().build()); } @Override public boolean hasTransientDatasource(String uid) { return delegate.hasTransientDatasource(uid); } @Override public void removeDatasource(Datasource datasource) { delegate.removeDatasource(securedDatasourceDecorator.undecorate(datasource)); } @Override public void removeTransientDatasource(@Nullable String uid) { delegate.removeTransientDatasource(uid); } private boolean isPermitted(String permission) { return authorizer.isPermitted(permission); } }