Package org.exist.security

Source Code of org.exist.security.SimpleACLPermissionTest

package org.exist.security;

import org.exist.storage.io.VariableByteInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.exist.storage.io.VariableByteOutputStream;
import org.exist.Database;
import org.exist.security.ACLPermission.ACE_TARGET;
import org.exist.security.ACLPermission.ACE_ACCESS_TYPE;
import org.exist.security.internal.SecurityManagerImpl;
import java.util.Random;
import org.easymock.EasyMock;
import org.exist.util.ByteArray;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import static org.easymock.classextension.EasyMock.expect;

/**
*
* @author Adam Retter <adam@exist-db.org>
*/
public class SimpleACLPermissionTest {

    private final static int ALL = Permission.READ | Permission.WRITE | Permission.EXECUTE;

    @Test
    public void add() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);
       
        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true);

        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);
       
        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
        assertEquals(0, permission.getACECount());

        final int userId = 1;
        final int mode = ALL;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, userId, mode);
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);
       
        assertEquals(1, permission.getACECount());
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(userId, permission.getACEId(0));
        assertEquals(mode, permission.getACEMode(0));
    }

    @Test
    public void addACE_ForUserWithModeString() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);
        final Account mockAccount = EasyMock.createMock(Account.class);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
        assertEquals(0, permission.getACECount());

        final int userId = 1112;
        final String userName = "aretter";
        final String mode = "rwx";

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true);

        expect(mockSecurityManager.getAccount(userName)).andReturn(mockAccount);
        expect(mockAccount.getId()).andReturn(userId);

        replay(mockSecurityManager, mockDatabase, mockCurrentSubject, mockAccount);

        permission.addACE(ACE_ACCESS_TYPE.ALLOWED, ACE_TARGET.USER, userName, mode);

        verify(mockSecurityManager, mockDatabase, mockCurrentSubject, mockAccount);

        assertEquals(1, permission.getACECount());
        assertEquals(userId, permission.getACEId(0));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(ALL, permission.getACEMode(0));
    }

    @Test
    public void addACE_ForGroupWithModeString() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);
        final Group mockGroup = EasyMock.createMock(Group.class);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
        assertEquals(0, permission.getACECount());

        final int groupId = 1112;
        final String groupName = "aretter";
        final String mode = "rwx";

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true);
       
        expect(mockSecurityManager.getGroup(groupName)).andReturn(mockGroup);
        expect(mockGroup.getId()).andReturn(groupId);

        replay(mockSecurityManager, mockDatabase, mockCurrentSubject, mockGroup);

        permission.addACE(ACE_ACCESS_TYPE.ALLOWED, ACE_TARGET.GROUP, groupName, mode);

        verify(mockSecurityManager, mockDatabase, mockCurrentSubject, mockGroup);

        assertEquals(1, permission.getACECount());
        assertEquals(groupId, permission.getACEId(0));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.GROUP, permission.getACETarget(0));
        assertEquals(ALL, permission.getACEMode(0));
        assertEquals(mode, permission.getACEModeString(0));
    }

    @Test
    public void insert_atFront_whenEmpty() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true);
       
        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);
       
        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
        assertEquals(0, permission.getACECount());

        final int userId = 1112;
        final int mode = ALL;

        permission.insertUserACE(0, ACE_ACCESS_TYPE.ALLOWED, userId, mode);
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);

        assertEquals(1, permission.getACECount());
        assertEquals(userId, permission.getACEId(0));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(ALL, permission.getACEMode(0));
    }

    @Test
    public void insert_atFront() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase).times(2);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject).times(2);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true).times(2);
       
        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);
       
        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
        assertEquals(0, permission.getACECount());

        final int userId = 1112;
        final int mode = ALL;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, userId, mode);
       
        assertEquals(1, permission.getACECount());
        assertEquals(userId, permission.getACEId(0));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(ALL, permission.getACEMode(0));

        final int secondUserId = 1113;
        final int secondMode = 04;
        permission.insertUserACE(0, ACE_ACCESS_TYPE.ALLOWED, secondUserId, secondMode);
       
        assertEquals(2, permission.getACECount());
        assertEquals(secondUserId, permission.getACEId(0));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(secondMode, permission.getACEMode(0));
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);
    }

    @Test
    public void insert_inMiddle() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase).times(3);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject).times(3);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true).times(3);
       
        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
       
        assertEquals(0, permission.getACECount());

        final int userId = 1112;
        final int mode = ALL;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, userId, mode);
       
        assertEquals(1, permission.getACECount());
       
        assertEquals(userId, permission.getACEId(0));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(ALL, permission.getACEMode(0));

        final int secondUserId = 1113;
        final int secondMode = 04;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, secondUserId, secondMode);
       
        assertEquals(2, permission.getACECount());
       
        assertEquals(secondUserId, permission.getACEId(1));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(1));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(1));
        assertEquals(secondMode, permission.getACEMode(1));

        final int thirdUserId = 1114;
        final int thirdMode = 02;
        permission.insertUserACE(1, ACE_ACCESS_TYPE.ALLOWED, thirdUserId, thirdMode);
       
        assertEquals(3, permission.getACECount());
       
        assertEquals(userId, permission.getACEId(0));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(ALL, permission.getACEMode(0));

        assertEquals(thirdUserId, permission.getACEId(1));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(1));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(1));
        assertEquals(thirdMode, permission.getACEMode(1));

        assertEquals(secondUserId, permission.getACEId(2));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(2));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(2));
        assertEquals(secondMode, permission.getACEMode(2));
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);
    }

    @Test(expected=PermissionDeniedException.class)
    public void insert_atEnd() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase).times(2);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject).times(2);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true).times(2);
       
        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
       
        assertEquals(0, permission.getACECount());

        final int userId = 1112;
        final int mode = ALL;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, userId, mode);
       
        assertEquals(1, permission.getACECount());
        assertEquals(userId, permission.getACEId(0));
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(ALL, permission.getACEMode(0));

        final int secondUserId = 1113;
        final int secondMode = 04;
        permission.insertUserACE(1, ACE_ACCESS_TYPE.ALLOWED, secondUserId, secondMode);
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);
    }

    @Test
    public void remove_firstACE() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase).times(3);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject).times(3);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true).times(3);
       
        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
       
        assertEquals(0, permission.getACECount());

        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, 1, ALL);
        final int secondUserId = 2;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, secondUserId, ALL);
        assertEquals(2, permission.getACECount());

        permission.removeACE(0);
        assertEquals(1, permission.getACECount());
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(secondUserId, permission.getACEId(0));
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);
    }

    @Test
    public void remove_middleACE() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase).times(4);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject).times(4);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true).times(4);

        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);
       
        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
       
        assertEquals(0, permission.getACECount());

        final int firstUserId = 1;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, firstUserId, ALL);
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, 2, ALL);
        final int thirdUserId = 3;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, thirdUserId, ALL);
        assertEquals(3, permission.getACECount());

        permission.removeACE(1);
        assertEquals(2, permission.getACECount());
        assertEquals(firstUserId, permission.getACEId(0));
        assertEquals(thirdUserId, permission.getACEId(1));
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);
    }

    @Test
    public void remove_lastACE() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase).times(3);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject).times(3);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true).times(3);

        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
       
        assertEquals(0, permission.getACECount());

        final int firstUserId = 1;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, firstUserId, ALL);
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, 2, ALL);
        assertEquals(2, permission.getACECount());

        permission.removeACE(1);
        assertEquals(1, permission.getACECount());
        assertEquals(firstUserId, permission.getACEId(0));
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);
    }

    @Test
    public void modify() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase).times(3);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject).times(3);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true).times(3);

        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
       
        assertEquals(0, permission.getACECount());

        final int userId = 1;
        final int mode = Permission.READ;
        final ACE_ACCESS_TYPE access_type = ACE_ACCESS_TYPE.ALLOWED;
        permission.addUserACE(access_type, userId, mode);

        assertEquals(1, permission.getACECount());
        assertEquals(userId, permission.getACEId(0));
        assertEquals(access_type, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(mode, permission.getACEMode(0));

        permission.modifyACE(0, access_type, Permission.WRITE);

        assertEquals(1, permission.getACECount());
        assertEquals(userId, permission.getACEId(0));
        assertEquals(access_type, permission.getACEAccessType(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(Permission.WRITE, permission.getACEMode(0));

        permission.modifyACE(0, ACE_ACCESS_TYPE.DENIED, Permission.READ | Permission.WRITE);

        assertEquals(1, permission.getACECount());
        assertEquals(userId, permission.getACEId(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(ACE_ACCESS_TYPE.DENIED, permission.getACEAccessType(0));
        assertEquals(Permission.READ | Permission.WRITE, permission.getACEMode(0));
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);
    }

    @Test
    public void clear() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);

        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase).times(3);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject).times(3);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true).times(3);

        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
        assertEquals(0, permission.getACECount());

        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, 1, ALL);
        final int secondUserId = 2;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, secondUserId, ALL);
        assertEquals(2, permission.getACECount());

        permission.clear();

        assertEquals(0, permission.getACECount());
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);
    }

    @Test
    public void validate_cant_read_when_readNotInACL() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);

        final int ownerId = new Random().nextInt(SecurityManagerImpl.MAX_USER_ID);
        final int mode = 0700;
        final int ownerGroupId = new Random().nextInt(SecurityManagerImpl.MAX_GROUP_ID);

        final Subject mockUser = EasyMock.createMock(Subject.class);
        final boolean mockUserHasDbaRole = false;
        final int mockUserId = new Random().nextInt(SecurityManagerImpl.MAX_USER_ID);

        expect(mockUser.hasDbaRole()).andReturn(mockUserHasDbaRole);
        expect(mockUser.getId()).andReturn(mockUserId);
        expect(mockUser.getGroupIds()).andReturn(new int[0]);

        replay(mockSecurityManager, mockUser);

        Permission permission = new SimpleACLPermission(mockSecurityManager, ownerId, ownerGroupId, mode);

        boolean isValid = permission.validate(mockUser, Permission.READ);

        verify(mockSecurityManager, mockUser);

        assertFalse(isValid);
    }

    @Test
    public void validate_read_when_readInACL() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);
       
        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true);

        final int ownerId = new Random().nextInt(SecurityManagerImpl.MAX_USER_ID);
        final int mode = 0700;
        final int ownerGroupId = new Random().nextInt(SecurityManagerImpl.MAX_GROUP_ID);

        final Subject mockUser = EasyMock.createMock(Subject.class);
        final boolean mockUserHasDbaRole = false;
        final int mockUserId = new Random().nextInt(SecurityManagerImpl.MAX_USER_ID);

        expect(mockUser.hasDbaRole()).andReturn(mockUserHasDbaRole);
        expect(mockUser.getId()).andReturn(mockUserId);
        expect(mockUser.getGroupIds()).andReturn(new int[0]);

        replay(mockSecurityManager, mockDatabase, mockCurrentSubject, mockUser);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager, ownerId, ownerGroupId, mode);
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, mockUserId, Permission.READ);

        boolean isValid = permission.validate(mockUser, Permission.READ);

        verify(mockSecurityManager, mockDatabase, mockCurrentSubject, mockUser);

        assertTrue(isValid);
    }

    @Test
    public void validate_cant_read_ACL_ordered_entries() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);
       
        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase).times(2);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject).times(2);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true).times(2);

        final int ownerId = new Random().nextInt(SecurityManagerImpl.MAX_USER_ID);
        final int mode = 0700;
        final int ownerGroupId = new Random().nextInt(SecurityManagerImpl.MAX_GROUP_ID);

        /**
         * We create ACE entries which has -
         * 1) user "userA" who is DENIED READ access
         * 2) group "groupA" who is ALLOWED READ access
         *
         * userA is a member of groupA, and so should still be DENIED read access
         * as the ACL is evaluated top-down
         *
         */
        final Subject mockUser = EasyMock.createMock(Subject.class);
        final boolean mockUserHasDbaRole = false;
        final int mockUserId = new Random().nextInt(SecurityManagerImpl.MAX_USER_ID);
        final int mockGroupId = new Random().nextInt(SecurityManagerImpl.MAX_GROUP_ID);

        expect(mockUser.hasDbaRole()).andReturn(mockUserHasDbaRole);
        expect(mockUser.getId()).andReturn(mockUserId);
        expect(mockUser.getGroupIds()).andReturn(new int[0]);

        replay(mockSecurityManager, mockDatabase, mockCurrentSubject, mockUser);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager, ownerId, ownerGroupId, mode);
       
        permission.addUserACE(ACE_ACCESS_TYPE.DENIED, mockUserId, Permission.READ);
        permission.addGroupACE(ACE_ACCESS_TYPE.ALLOWED, mockGroupId, Permission.READ);

        boolean isValid = permission.validate(mockUser, Permission.READ);

        verify(mockSecurityManager, mockDatabase, mockCurrentSubject, mockUser);

        assertFalse(isValid);
    }

    @Test
    public void validate_can_write_ACL_ordered_entries() throws PermissionDeniedException {
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);
       
        //expect(mockSecurityManager.getDatabase()).andReturn(mockDatabase).times(2);
        //expect(mockDatabase.getSubject()).andReturn(mockCurrentSubject).times(2);
        //expect(mockCurrentSubject.hasDbaRole()).andReturn(true).times(2);

        final int ownerId = new Random().nextInt(SecurityManagerImpl.MAX_USER_ID);
        final int mode = 0700;
        final int ownerGroupId = new Random().nextInt(SecurityManagerImpl.MAX_GROUP_ID);

        /**
         * We create ACE entries which has -
         * 1) user "userA" who is DENIED READ access
         * 2) group "groupA" who is ALLOWED WRITE access
         *
         * userA is a member of groupA, and so should still be ALLOWED write access
         * as the ACL is evaluated top-down
         *
         */
        final Subject mockUser = EasyMock.createMock(Subject.class);
        final boolean mockUserHasDbaRole = false;
        final int mockUserId = new Random().nextInt(SecurityManagerImpl.MAX_USER_ID);
        final int mockGroupId = new Random().nextInt(SecurityManagerImpl.MAX_GROUP_ID);

        expect(mockUser.hasDbaRole()).andReturn(mockUserHasDbaRole);
        expect(mockUser.getId()).andReturn(mockUserId);
        expect(mockUser.getGroupIds()).andReturn(new int[]{mockGroupId});

        replay(mockSecurityManager, mockDatabase, mockCurrentSubject, mockUser);

        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager, ownerId, ownerGroupId, mode);

        permission.addUserACE(ACE_ACCESS_TYPE.DENIED, mockUserId, Permission.READ);
        permission.addGroupACE(ACE_ACCESS_TYPE.ALLOWED, mockGroupId, Permission.WRITE);

        boolean isValid = permission.validate(mockUser, Permission.WRITE);

        verify(mockSecurityManager, mockUser);

        assertTrue(isValid);
    }
   
    @Test
    public void roundtrip_write_read() throws PermissionDeniedException, IOException {
       
        final SecurityManager mockSecurityManager = EasyMock.createMock(SecurityManager.class);
        final Database mockDatabase = EasyMock.createMock(Database.class);
        final Subject mockCurrentSubject = EasyMock.createMock(Subject.class);
       
        replay(mockSecurityManager, mockDatabase, mockCurrentSubject);
       
        SimpleACLPermission permission = new SimpleACLPermission(mockSecurityManager);
       
        assertEquals(0, permission.getACECount());

        final int userId1 = 1;
        final int mode1 = ALL;
        permission.addUserACE(ACE_ACCESS_TYPE.ALLOWED, userId1, mode1);
       
        final int groupId2 = 2;
        final int mode2 = Permission.READ;
        permission.addGroupACE(ACE_ACCESS_TYPE.DENIED, groupId2, mode2);
       
        final VariableByteOutputStream os = new VariableByteOutputStream();
       
        //write the acl out
        permission.write(os);
       
        verify(mockSecurityManager, mockDatabase, mockCurrentSubject);
       
        assertEquals(2, permission.getACECount());
       
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission.getACEAccessType(0));
        assertEquals(userId1, permission.getACEId(0));
        assertEquals(ACE_TARGET.USER, permission.getACETarget(0));
        assertEquals(mode1, permission.getACEMode(0));
       
        assertEquals(ACE_ACCESS_TYPE.DENIED, permission.getACEAccessType(1));
        assertEquals(groupId2, permission.getACEId(1));
        assertEquals(ACE_TARGET.GROUP, permission.getACETarget(1));
        assertEquals(mode2, permission.getACEMode(1));
       
        //get the written acl data
        ByteArray buf = os.data();
        byte data[] = new byte[buf.size()];
        buf.copyTo(data, 0);
       
       
        //create a new permission instance
        SimpleACLPermission permission2 = new SimpleACLPermission(mockSecurityManager);
       
        //read the acl in
        permission2.read(new VariableByteInputStream(new ByteArrayInputStream(data)));
       
        assertEquals(2, permission2.getACECount());
       
        assertEquals(ACE_ACCESS_TYPE.ALLOWED, permission2.getACEAccessType(0));
        assertEquals(userId1, permission2.getACEId(0));
        assertEquals(ACE_TARGET.USER, permission2.getACETarget(0));
        assertEquals(mode1, permission2.getACEMode(0));
       
        assertEquals(ACE_ACCESS_TYPE.DENIED, permission2.getACEAccessType(1));
        assertEquals(groupId2, permission2.getACEId(1));
        assertEquals(ACE_TARGET.GROUP, permission2.getACETarget(1));
        assertEquals(mode2, permission2.getACEMode(1));
    }
}
TOP

Related Classes of org.exist.security.SimpleACLPermissionTest

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.