use of mondrian.olap.Role.HierarchyAccess in project mondrian by pentaho.
the class AccessControlTest method testUnionRole.
// todo: performance test where 1 of 1000 children is not visible
public void testUnionRole() {
final TestContext testContext = TestContext.instance().create(null, null, null, null, null, "<Role name=\"Role1\">\n" + " <SchemaGrant access=\"none\">\n" + " <CubeGrant cube=\"Sales\" access=\"all\">\n" + " <HierarchyGrant hierarchy=\"[Customers]\" access=\"custom\" rollupPolicy=\"Partial\">\n" + " <MemberGrant member=\"[Customers].[USA].[CA]\" access=\"all\"/>\n" + " <MemberGrant member=\"[Customers].[USA].[CA].[San Francisco].[Gladys Evans]\" access=\"none\"/>\n" + " </HierarchyGrant>\n" + " <HierarchyGrant hierarchy=\"[Promotion Media]\" access=\"all\"/>\n" + " <HierarchyGrant hierarchy=\"[Marital Status]\" access=\"none\"/>\n" + " <HierarchyGrant hierarchy=\"[Gender]\" access=\"none\"/>\n" + " <HierarchyGrant hierarchy=\"[Store]\" access=\"custom\" rollupPolicy=\"Partial\" topLevel=\"[Store].[Store State]\"/>\n" + " </CubeGrant>\n" + " <CubeGrant cube=\"Warehouse\" access=\"all\"/>\n" + " </SchemaGrant>\n" + "</Role>\n" + "<Role name=\"Role2\">\n" + " <SchemaGrant access=\"none\">\n" + " <CubeGrant cube=\"Sales\" access=\"none\">\n" + " <HierarchyGrant hierarchy=\"[Customers]\" access=\"custom\" rollupPolicy=\"Hidden\">\n" + " <MemberGrant member=\"[Customers].[USA]\" access=\"all\"/>\n" + " <MemberGrant member=\"[Customers].[USA].[CA]\" access=\"none\"/>\n" + " <MemberGrant member=\"[Customers].[USA].[OR]\" access=\"none\"/>\n" + " <MemberGrant member=\"[Customers].[USA].[OR].[Portland]\" access=\"all\"/>\n" + " </HierarchyGrant>\n" + " <HierarchyGrant hierarchy=\"[Store]\" access=\"all\" rollupPolicy=\"Hidden\"/>\n" + " </CubeGrant>\n" + " </SchemaGrant>\n" + "</Role>\n");
Connection connection;
try {
connection = testContext.withRole("Role3,Role2").getConnection();
fail("expected exception, got " + connection);
} catch (RuntimeException e) {
final String message = e.getMessage();
assertTrue(message, message.indexOf("Role 'Role3' not found") >= 0);
}
try {
connection = testContext.withRole("Role1,Role3").getConnection();
fail("expected exception, got " + connection);
} catch (RuntimeException e) {
final String message = e.getMessage();
assertTrue(message, message.indexOf("Role 'Role3' not found") >= 0);
}
connection = testContext.withRole("Role1,Role2").getConnection();
// Cube access:
// Both can see [Sales]
// Role1 only see [Warehouse]
// Neither can see [Warehouse and Sales]
assertCubeAccess(connection, Access.ALL, "Sales");
assertCubeAccess(connection, Access.ALL, "Warehouse");
assertCubeAccess(connection, Access.NONE, "Warehouse and Sales");
// Hierarchy access:
// Both can see [Customers] with Custom access
// Both can see [Store], Role1 with Custom access, Role2 with All access
// Role1 can see [Promotion Media], Role2 cannot
// Neither can see [Marital Status]
assertHierarchyAccess(connection, Access.CUSTOM, "Sales", "[Customers]");
assertHierarchyAccess(connection, Access.ALL, "Sales", "[Store]");
assertHierarchyAccess(connection, Access.ALL, "Sales", "[Promotion Media]");
assertHierarchyAccess(connection, Access.NONE, "Sales", "[Marital Status]");
// Rollup policy is the greater of Role1's partian and Role2's hidden
final Role.HierarchyAccess hierarchyAccess = getHierarchyAccess(connection, "Sales", "[Store]");
assertEquals(Role.RollupPolicy.PARTIAL, hierarchyAccess.getRollupPolicy());
// One of the roles is restricting the levels, so we
// expect only the levels from 2 to 4 to be available.
assertEquals(2, hierarchyAccess.getTopLevelDepth());
assertEquals(4, hierarchyAccess.getBottomLevelDepth());
// Member access:
// both can see [USA]
assertMemberAccess(connection, Access.CUSTOM, "[Customers].[USA]");
// Role1 can see [CA], Role2 cannot
assertMemberAccess(connection, Access.CUSTOM, "[Customers].[USA].[CA]");
// Role1 cannoy see [USA].[OR].[Portland], Role2 can
assertMemberAccess(connection, Access.ALL, "[Customers].[USA].[OR].[Portland]");
// Role1 cannot see [USA].[OR], Role2 can see it by virtue of [Portland]
assertMemberAccess(connection, Access.CUSTOM, "[Customers].[USA].[OR]");
// Neither can see Beaverton
assertMemberAccess(connection, Access.NONE, "[Customers].[USA].[OR].[Beaverton]");
// Rollup policy
String mdx = "select Hierarchize(\n" + "{[Customers].[USA].Children,\n" + " [Customers].[USA].[OR].Children}) on 0\n" + "from [Sales]";
testContext.assertQueryReturns(mdx, "Axis #0:\n" + "{}\n" + "Axis #1:\n" + "{[Customers].[USA].[CA]}\n" + "{[Customers].[USA].[OR]}\n" + "{[Customers].[USA].[OR].[Albany]}\n" + "{[Customers].[USA].[OR].[Beaverton]}\n" + "{[Customers].[USA].[OR].[Corvallis]}\n" + "{[Customers].[USA].[OR].[Lake Oswego]}\n" + "{[Customers].[USA].[OR].[Lebanon]}\n" + "{[Customers].[USA].[OR].[Milwaukie]}\n" + "{[Customers].[USA].[OR].[Oregon City]}\n" + "{[Customers].[USA].[OR].[Portland]}\n" + "{[Customers].[USA].[OR].[Salem]}\n" + "{[Customers].[USA].[OR].[W. Linn]}\n" + "{[Customers].[USA].[OR].[Woodburn]}\n" + "{[Customers].[USA].[WA]}\n" + "Row #0: 74,748\n" + "Row #0: 67,659\n" + "Row #0: 6,806\n" + "Row #0: 4,558\n" + "Row #0: 9,539\n" + "Row #0: 4,910\n" + "Row #0: 9,596\n" + "Row #0: 5,145\n" + "Row #0: 3,708\n" + "Row #0: 3,583\n" + "Row #0: 7,678\n" + "Row #0: 4,175\n" + "Row #0: 7,961\n" + "Row #0: 124,366\n");
testContext.withRole("Role1").assertQueryThrows(mdx, "MDX object '[Customers].[USA].[OR]' not found in cube 'Sales'");
testContext.withRole("Role2").assertQueryThrows(mdx, "MDX cube 'Sales' not found");
// Compared to above:
// a. cities in Oregon are missing besides Portland
// b. total for Oregon = total for Portland
testContext.withRole("Role1,Role2").assertQueryReturns(mdx, "Axis #0:\n" + "{}\n" + "Axis #1:\n" + "{[Customers].[USA].[CA]}\n" + "{[Customers].[USA].[OR]}\n" + "{[Customers].[USA].[OR].[Portland]}\n" + "{[Customers].[USA].[WA]}\n" + "Row #0: 74,742\n" + "Row #0: 3,583\n" + "Row #0: 3,583\n" + "Row #0: 124,366\n");
checkQuery(testContext.withRole("Role1,Role2"), mdx);
}
use of mondrian.olap.Role.HierarchyAccess in project mondrian by pentaho.
the class AccessControlTest method testUnionRoleHasInaccessibleDescendants.
/**
* This is a test for
* <a href="http://jira.pentaho.com/browse/MONDRIAN-1384">MONDRIAN-1384</a>
*/
public void testUnionRoleHasInaccessibleDescendants() throws Exception {
final TestContext testContext = TestContext.instance().create(null, null, null, null, null, "<Role name=\"Role1\">\n" + " <SchemaGrant access=\"none\">\n" + " </SchemaGrant>\n" + "</Role>\n" + "<Role name=\"Role2\">\n" + " <SchemaGrant access=\"all\">\n" + " <CubeGrant cube=\"Sales\" access=\"all\">\n" + " <HierarchyGrant hierarchy=\"[Customers]\" access=\"custom\" rollupPolicy=\"partial\">\n" + " <MemberGrant member=\"[Customers].[USA].[OR]\" access=\"all\"/>\n" + " </HierarchyGrant>\n" + " </CubeGrant>\n" + " </SchemaGrant>\n" + "</Role>\n");
final Connection connection = testContext.withRole("Role1,Role2").getConnection();
final Cube cube = connection.getSchema().lookupCube("Sales", true);
final HierarchyAccess accessDetails = connection.getRole().getAccessDetails(cube.lookupHierarchy(new Id.NameSegment("Customers", Id.Quoting.UNQUOTED), false));
final SchemaReader scr = cube.getSchemaReader(null).withLocus();
assertEquals(true, accessDetails.hasInaccessibleDescendants(scr.getMemberByUniqueName(Util.parseIdentifier("[Customers].[USA]"), true)));
}
use of mondrian.olap.Role.HierarchyAccess in project mondrian by pentaho.
the class RolapHierarchy method getLowestMembersForAccess.
/**
* Goes recursively down a hierarchy and builds a list of the
* members that should be constrained on because of access controls.
* It isn't sufficient to constrain on the current level in the
* evaluator because the actual constraint could be even more limited
* <p>Example. If we only give access to Seattle but the query is on
* the country level, we have to constrain at the city level, not state,
* or else all the values of all cities in the state will be returned.
*/
List<Member> getLowestMembersForAccess(Evaluator evaluator, HierarchyAccess hAccess, Map<Member, Access> membersWithAccess) {
if (membersWithAccess == null) {
membersWithAccess = FunUtil.getNonEmptyMemberChildrenWithDetails(evaluator, ((RolapEvaluator) evaluator).getExpanding());
}
boolean goesLower = false;
for (Member member : membersWithAccess.keySet()) {
Access access = membersWithAccess.get(member);
if (access == null) {
access = hAccess.getAccess(member);
}
if (access != Access.ALL) {
goesLower = true;
break;
}
}
if (goesLower) {
// We still have to go one more level down.
Map<Member, Access> newMap = new HashMap<Member, Access>();
for (Member member : membersWithAccess.keySet()) {
int savepoint = evaluator.savepoint();
try {
evaluator.setContext(member);
newMap.putAll(FunUtil.getNonEmptyMemberChildrenWithDetails(evaluator, member));
} finally {
evaluator.restore(savepoint);
}
}
// Now pass it recursively to this method.
return getLowestMembersForAccess(evaluator, hAccess, newMap);
}
return new ArrayList<Member>(membersWithAccess.keySet());
}
use of mondrian.olap.Role.HierarchyAccess in project mondrian by pentaho.
the class RestrictedMemberReaderTest method testGetHierarchy_allAccess.
public void testGetHierarchy_allAccess() {
Schema schema = Mockito.mock(Schema.class);
Dimension dimension = Mockito.mock(Dimension.class);
RolapHierarchy hierarchy = Mockito.mock(RolapHierarchy.class);
Level[] hierarchyAccessLevels = new Level[] { null };
MemberReader delegateMemberReader = Mockito.mock(MemberReader.class);
HierarchyAccess roleAccess = null;
Role role = Mockito.mock(Role.class);
Mockito.doReturn(schema).when(dimension).getSchema();
Mockito.doReturn(dimension).when(hierarchy).getDimension();
Mockito.doReturn(hierarchyAccessLevels).when(hierarchy).getLevels();
Mockito.doReturn(true).when(hierarchy).isRagged();
Mockito.doReturn(roleAccess).when(role).getAccessDetails(Mockito.any(Hierarchy.class));
Mockito.doReturn(hierarchy).when(delegateMemberReader).getHierarchy();
rmr = new RestrictedMemberReader(delegateMemberReader, role);
Assert.assertSame(hierarchy, rmr.getHierarchy());
}
use of mondrian.olap.Role.HierarchyAccess in project mondrian by pentaho.
the class RestrictedMemberReaderTest method testDefaultMember_allAccess.
public void testDefaultMember_allAccess() {
Schema schema = Mockito.mock(Schema.class);
Dimension dimension = Mockito.mock(Dimension.class);
RolapHierarchy hierarchy = Mockito.mock(RolapHierarchy.class);
Level[] hierarchyAccessLevels = new Level[] { null };
MemberReader delegateMemberReader = Mockito.mock(MemberReader.class);
HierarchyAccess roleAccess = null;
Role role = Mockito.mock(Role.class);
Mockito.doReturn(schema).when(dimension).getSchema();
Mockito.doReturn(dimension).when(hierarchy).getDimension();
Mockito.doReturn(hierarchyAccessLevels).when(hierarchy).getLevels();
Mockito.doReturn(true).when(hierarchy).isRagged();
Mockito.doReturn(roleAccess).when(role).getAccessDetails(Mockito.any(Hierarchy.class));
Mockito.doReturn(hierarchy).when(delegateMemberReader).getHierarchy();
RolapMember hDefaultMember = mockMember();
Mockito.doReturn(hDefaultMember).when(hierarchy).getDefaultMember();
rmr = new RestrictedMemberReader(delegateMemberReader, role);
Assert.assertSame(hDefaultMember, rmr.getDefaultMember());
}
Aggregations