/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.jdbc;
import static org.junit.Assert.*;
import java.io.FileInputStream;
import java.security.Identity;
import java.security.Principal;
import java.security.acl.Group;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Vector;
import javax.security.auth.Subject;
import org.junit.After;
import org.junit.Test;
import org.mockito.Mockito;
import org.teiid.core.util.UnitTestUtil;
import org.teiid.metadata.Column;
import org.teiid.metadata.MetadataFactory;
import org.teiid.metadata.Table;
import org.teiid.metadata.Table.Type;
import org.teiid.runtime.DoNothingSecurityHelper;
import org.teiid.runtime.EmbeddedConfiguration;
import org.teiid.runtime.EmbeddedServer;
import org.teiid.runtime.HardCodedExecutionFactory;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.TypeFacility;
@SuppressWarnings("nls")
public class TestRowBasedSecurity {
private EmbeddedServer es;
@After public void tearDown() {
es.stop();
}
@Test public void testSecurity() throws Exception {
es = new EmbeddedServer();
EmbeddedConfiguration ec = new EmbeddedConfiguration();
final Vector<Principal> v = new Vector<Principal>();
v.add(new Identity("myrole") {});
final Subject subject = new Subject();
Group g = Mockito.mock(Group.class);
Mockito.stub(g.getName()).toReturn("Roles");
Mockito.stub(g.members()).toReturn((Enumeration) v.elements());
subject.getPrincipals().add(g);
ec.setSecurityHelper(new DoNothingSecurityHelper() {
@Override
public Subject getSubjectInContext(String securityDomain) {
return subject;
}
@Override
public Subject getSubjectInContext(Object context) {
return subject;
}
});
es.start(ec);
HardCodedExecutionFactory hcef = new HardCodedExecutionFactory() {
@Override
public void getMetadata(MetadataFactory metadataFactory, Object conn) throws TranslatorException {
Table t = metadataFactory.addTable("x");
Column col = metadataFactory.addColumn("col", TypeFacility.RUNTIME_NAMES.STRING, t);
metadataFactory.addColumn("col2", TypeFacility.RUNTIME_NAMES.STRING, t);
metadataFactory.addPermission("y", t, null, null, Boolean.TRUE, null, null, null, "col = 'a'", null);
metadataFactory.addColumnPermission("y", col, null, null, null, null, "null", null);
t = metadataFactory.addTable("y");
col = metadataFactory.addColumn("col", TypeFacility.RUNTIME_NAMES.STRING, t);
metadataFactory.addColumn("col2", TypeFacility.RUNTIME_NAMES.STRING, t);
metadataFactory.addPermission("z", t, null, null, null, null, null, null, "col = 'e'", null);
Table v = metadataFactory.addTable("v");
metadataFactory.addPermission("y", v, null, null, Boolean.TRUE, null, null, null, null, null);
col = metadataFactory.addColumn("col", TypeFacility.RUNTIME_NAMES.STRING, v);
metadataFactory.addColumn("col2", TypeFacility.RUNTIME_NAMES.STRING, v);
v.setTableType(Type.View);
v.setVirtual(true);
v.setSelectTransformation("/*+ cache(scope:session) */ select col, col2 from y");
}
@Override
public boolean isSourceRequiredForMetadata() {
return false;
}
};
hcef.addData("SELECT x.col, x.col2 FROM x", Arrays.asList(Arrays.asList("a", "b"), Arrays.asList("c", "d")));
hcef.addData("SELECT y.col, y.col2 FROM y", Arrays.asList(Arrays.asList("e", "f"), Arrays.asList("h", "g")));
es.addTranslator("hc", hcef);
es.deployVDB(new FileInputStream(UnitTestUtil.getTestDataFile("roles-vdb.xml")));
Connection c = es.getDriver().connect("jdbc:teiid:z;PassthroughAuthentication=true", null);
Statement s = c.createStatement();
ResultSet rs = s.executeQuery("select * from x");
rs.next();
assertEquals(null, rs.getString(1)); //masking
assertEquals("b", rs.getString(2));
assertFalse(rs.next()); //row filter
rs.close();
s = c.createStatement();
rs = s.executeQuery("select lookup('myschema.x', 'col', 'col2', 'b')");
rs.next();
assertEquals(null, rs.getString(1)); //global scoped
s = c.createStatement();
rs = s.executeQuery("select count(col2) from v where col is not null");
rs.next();
assertEquals(1, rs.getInt(1));
//different session with different roles
v.clear();
c = es.getDriver().connect("jdbc:teiid:z;PassthroughAuthentication=true", null);
s = c.createStatement();
rs = s.executeQuery("select count(col2) from v where col is not null");
rs.next();
assertEquals(2, rs.getInt(1));
}
}