Search in sources :

Example 1 with HierarchyAccess

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);
}
Also used : HierarchyAccess(mondrian.olap.Role.HierarchyAccess)

Example 2 with HierarchyAccess

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)));
}
Also used : HierarchyAccess(mondrian.olap.Role.HierarchyAccess)

Example 3 with HierarchyAccess

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());
}
Also used : HierarchyAccess(mondrian.olap.Role.HierarchyAccess) MultiCardinalityDefaultMember(mondrian.rolap.RestrictedMemberReader.MultiCardinalityDefaultMember) MemberChildrenConstraint(mondrian.rolap.sql.MemberChildrenConstraint)

Example 4 with HierarchyAccess

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());
}
Also used : Role(mondrian.olap.Role) Hierarchy(mondrian.olap.Hierarchy) Schema(mondrian.olap.Schema) Level(mondrian.olap.Level) Dimension(mondrian.olap.Dimension) HierarchyAccess(mondrian.olap.Role.HierarchyAccess)

Example 5 with HierarchyAccess

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());
}
Also used : Role(mondrian.olap.Role) Hierarchy(mondrian.olap.Hierarchy) Schema(mondrian.olap.Schema) Level(mondrian.olap.Level) Dimension(mondrian.olap.Dimension) HierarchyAccess(mondrian.olap.Role.HierarchyAccess)

Aggregations

HierarchyAccess (mondrian.olap.Role.HierarchyAccess)12 Hierarchy (mondrian.olap.Hierarchy)7 Role (mondrian.olap.Role)7 MultiCardinalityDefaultMember (mondrian.rolap.RestrictedMemberReader.MultiCardinalityDefaultMember)5 Dimension (mondrian.olap.Dimension)2 Level (mondrian.olap.Level)2 Schema (mondrian.olap.Schema)2 PrintWriter (java.io.PrintWriter)1 mondrian.olap (mondrian.olap)1 DimensionType (mondrian.olap.DimensionType)1 LevelType (mondrian.olap.LevelType)1 MemberChildrenConstraint (mondrian.rolap.sql.MemberChildrenConstraint)1