Package org.apache.jackrabbit.oak.security.user

Source Code of org.apache.jackrabbit.oak.security.user.MembershipProviderTest

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.jackrabbit.oak.security.user;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.jcr.RepositoryException;

import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.oak.AbstractSecurityTest;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertNull;

/**
* Tests large group and user graphs.
* <ul>
*     <li>{@link #NUM_USERS} users</li>
*     <li>{@link #NUM_GROUPS} groups</li>
*     <li>1 group with all users</li>
*     <li>1 user with all groups</li>
* </ul>
*
* @since OAK 1.0
*/
public class MembershipProviderTest extends AbstractSecurityTest {

    private static final int NUM_USERS = 1000;
    private static final int NUM_GROUPS = 1000;
    private static final int SIZE_TH = 10;

    private UserManagerImpl userMgr;
    private Set<String> testUsers = new HashSet<String>();
    private Set<String> testGroups = new HashSet<String>();

    @Before
    public void before() throws Exception {
        super.before();
        testUsers.clear();
        testGroups.clear();
        userMgr = new UserManagerImpl(root, namePathMapper, getSecurityProvider());
        // set the membership size threshold low for testing
        userMgr.getMembershipProvider().setMembershipSizeThreshold(SIZE_TH);
    }

    @After
    public void after() throws Exception {
        try {
            for (String authId: testGroups) {
                Authorizable auth = userMgr.getAuthorizable(authId);
                if (auth != null) {
                    auth.remove();
                }
            }
            for (String authId: testUsers) {
                Authorizable auth = userMgr.getAuthorizable(authId);
                if (auth != null) {
                    auth.remove();
                }
            }
            root.commit();
        } finally {
            super.after();
        }
    }

    @Test
    public void testManyMembers() throws Exception {
        Set<String> members = new HashSet<String>();
        Group grp  = createGroup();
        for (int i=0; i<NUM_USERS; i++) {
            User usr = createUser();
            grp.addMember(usr);
            members.add(usr.getID());
        }
        root.commit();
        checkMembers(grp, members);

        // also check storage structure
        Tree tree = root.getTree(grp.getPath());
        assertEquals(
                "rep:members property must have correct number of references",
                SIZE_TH,
                tree.getProperty(UserConstants.REP_MEMBERS).count()
        );

        Tree membersList = tree.getChild(UserConstants.REP_MEMBERS_LIST);
        assertTrue(
                "rep:memberList must exist",
                membersList.exists()
        );

        assertEquals(
                "rep:memberList must have correct primary type.",
                UserConstants.NT_REP_MEMBER_REFERENCES_LIST,
                membersList.getProperty(JcrConstants.JCR_PRIMARYTYPE).getValue(Type.STRING)
        );

        assertEquals(
                "rep:memberList must have correct number of child nodes.",
                (NUM_USERS / SIZE_TH) - 1,
                membersList.getChildrenCount(Long.MAX_VALUE)
        );
    }

    @Test
    public void testManyMemberships() throws Exception {
        Set<String> memberships = new HashSet<String>();
        User usr = createUser();
        for (int i=0; i<NUM_GROUPS; i++) {
            Group grp = createGroup();
            grp.addMember(usr);
            memberships.add(grp.getID());
        }
        root.commit();

        Iterator<Group> iter = usr.declaredMemberOf();
        while (iter.hasNext()) {
            Group group = iter.next();
            Assert.assertTrue(memberships.remove(group.getID()));
        }
        assertEquals(0, memberships.size());
    }

    @Test
    public void testNestedMembers() throws Exception {
        Set<String> members = new HashSet<String>();
        Set<String> declaredMembers = new HashSet<String>();
        Group grp  = createGroup();
        for (int i=0; i<10; i++) {
            Group g1 = createGroup();
            grp.addMember(g1);
            members.add(g1.getID());
            declaredMembers.add(g1.getID());
            for (int j=0; j<10; j++) {
                Group g2 = createGroup();
                g1.addMember(g2);
                members.add(g2.getID());
                for (int k=0; k<10; k++) {
                    User usr = createUser();
                    g2.addMember(usr);
                    members.add(usr.getID());
                }
            }
        }
        root.commit();

        checkMembers(grp, members);

        Iterator<Authorizable> iter = grp.getDeclaredMembers();
        while (iter.hasNext()) {
            Authorizable member = iter.next();
            Assert.assertTrue(declaredMembers.remove(member.getID()));
        }
        assertEquals(0, declaredMembers.size());
    }

    @Test
    public void testNestedMemberships() throws Exception {
        Set<String> memberships = new HashSet<String>();
        User user  = createUser();
        Group grp = createGroup();
        memberships.add(grp.getID());
        for (int i=0; i<10; i++) {
            Group g1 = createGroup();
            grp.addMember(g1);
            memberships.add(g1.getID());
            for (int j=0; j<10; j++) {
                Group g2 = createGroup();
                g1.addMember(g2);
                memberships.add(g2.getID());
                g2.addMember(user);
            }
        }
        root.commit();

        Iterator<Group> iter = user.memberOf();
        while (iter.hasNext()) {
            Group group = iter.next();
            Assert.assertTrue(memberships.remove(group.getID()));
        }
        assertEquals(0, memberships.size());
    }

    @Test
    public void testRemoveMembers() throws Exception {
        Set<String> members = new HashSet<String>();
        String[] users = new String[NUM_USERS];
        Group grp  = createGroup();
        for (int i=0; i<NUM_USERS; i++) {
            User usr = createUser();
            grp.addMember(usr);
            members.add(usr.getID());
            users[i] = usr.getID();
        }
        root.commit();

        // remove the first TH users, this should remove all references from rep:members in the group node and remove
        // the rep:members property
        for (int i=0; i<SIZE_TH; i++) {
            Authorizable auth = userMgr.getAuthorizable(users[i]);
            members.remove(users[i]);
            grp.removeMember(auth);
        }
        root.commit();

        checkMembers(grp, members);

        // also check storage structure
        Tree tree = root.getTree(grp.getPath());
        assertNull(
                "rep:members property not exist",
                tree.getProperty(UserConstants.REP_MEMBERS)
        );

        // now add TH/2 again.
        for (int i=0; i<SIZE_TH/2; i++) {
            Authorizable auth = userMgr.getAuthorizable(users[i]);
            members.add(users[i]);
            grp.addMember(auth);
        }
        root.commit();

        assertEquals(
                "rep:members property must have correct number of references",
                SIZE_TH / 2,
                tree.getProperty(UserConstants.REP_MEMBERS).count()
        );
        checkMembers(grp, members);

        // now remove the users 20-30, this should remove the 2nd overflow node
        for (int i=2*SIZE_TH; i< (3*SIZE_TH); i++) {
            Authorizable auth = userMgr.getAuthorizable(users[i]);
            members.remove(users[i]);
            grp.removeMember(auth);
        }
        root.commit();

        checkMembers(grp, members);

        Tree membersList = tree.getChild(UserConstants.REP_MEMBERS_LIST);
        assertFalse(
                "the first overflow node must not exist",
                membersList.getChild("1").exists()
        );

        // now add 10 users and check if the "1" node exists again
        for (int i=2*SIZE_TH; i< (3*SIZE_TH); i++) {
            Authorizable auth = userMgr.getAuthorizable(users[i]);
            members.add(users[i]);
            grp.addMember(auth);
        }
        root.commit();
        checkMembers(grp, members);

        membersList = tree.getChild(UserConstants.REP_MEMBERS_LIST);
        assertTrue(
                "the first overflow node must not exist",
                membersList.getChild("1").exists()
        );
    }

    private User createUser() throws RepositoryException {
        String userId = "testUser" + testUsers.size();
        User usr = userMgr.createUser(userId, "pw");
        testUsers.add(userId);
        if ((testUsers.size() + testGroups.size()) % 100 == 0) {
            System.out.println("created " + testGroups.size() + " groups, " + testUsers.size() + " users.");
        }
        return usr;
    }

    private Group createGroup() throws RepositoryException {
        String groupName = "testGroup" + testGroups.size();
        Group grp = userMgr.createGroup(groupName);
        testGroups.add(groupName);
        if ((testUsers.size() + testGroups.size()) % 100 == 0) {
            System.out.println("created " + testGroups.size() + " groups, " + testUsers.size() + " users.");
        }
        return grp;
    }

    private void checkMembers(Group grp, Set<String> ms) throws RepositoryException {
        Set<String> members = new HashSet<String>(ms);
        Iterator<Authorizable> iter = grp.getMembers();
        while (iter.hasNext()) {
            Authorizable member = iter.next();
            Assert.assertTrue("Group must have member", members.remove(member.getID()));
        }
        assertEquals("Group must have all members", 0, members.size());
    }
}
TOP

Related Classes of org.apache.jackrabbit.oak.security.user.MembershipProviderTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.