org.duracloud.account.security.vote.UserAccessDecisionVoterTest.java Source code

Java tutorial

Introduction

Here is the source code for org.duracloud.account.security.vote.UserAccessDecisionVoterTest.java

Source

/*
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 *
 *     http://duracloud.org/license/
 */
package org.duracloud.account.security.vote;

import org.aopalliance.intercept.MethodInvocation;
import org.duracloud.account.db.model.AccountInfo;
import org.duracloud.account.db.model.AccountRights;
import org.duracloud.account.db.model.DuracloudUser;
import org.duracloud.account.db.model.Role;
import org.duracloud.account.db.repo.DuracloudRepoMgr;
import org.duracloud.account.db.repo.DuracloudRightsRepo;
import org.duracloud.account.db.util.error.DBNotFoundException;
import org.duracloud.account.db.util.impl.DuracloudUserServiceImpl;
import org.duracloud.account.security.domain.SecuredRule;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import java.util.*;

/**
 * @author Andrew Woods
 *         Date: 4/6/11
 */
public class UserAccessDecisionVoterTest {

    private UserAccessDecisionVoter voter;

    private DuracloudRepoMgr repoMgr;

    private Authentication authentication;
    private MethodInvocation invocation;
    private Collection<ConfigAttribute> securityConfig;

    private final Role accessRole = Role.ROLE_USER;
    private final Role badRole = Role.ROLE_INIT;

    @Before
    public void setUp() throws Exception {
        repoMgr = EasyMock.createMock("DuracloudRepoMgr", DuracloudRepoMgr.class);
    }

    @After
    public void tearDown() throws Exception {
        EasyMock.verify(authentication, repoMgr, invocation);
    }

    @Test
    public void testVoteScopeAny() throws Exception {
        Role userRole = Role.ROLE_USER;
        int expectedDecision = AccessDecisionVoter.ACCESS_GRANTED;
        doTestScopeAny(userRole, expectedDecision);
    }

    @Test
    public void testVoteScopeAnyFail() {
        Role userRole = Role.ROLE_INIT;
        int expectedDecision = AccessDecisionVoter.ACCESS_DENIED;
        doTestScopeAny(userRole, expectedDecision);
    }

    private void doTestScopeAny(Role userRole, int expectedDecision) {
        Long userId = 5L;
        authentication = createAuthentication(userId, userRole.getRoleHierarchy());
        invocation = createInvocation(-1L, -1L, null);
        securityConfig = createSecurityConfig(SecuredRule.Scope.ANY);

        doTest(expectedDecision);
    }

    private void doTest(int expectedDecision) {
        replayMocks();
        voter = new UserAccessDecisionVoter(repoMgr);

        int decision = voter.vote(authentication, invocation, securityConfig);
        Assert.assertEquals(expectedDecision, decision);
    }

    @Test
    public void testScopeSelfAcctPeer() throws DBNotFoundException {
        Role otherUserRole = Role.ROLE_USER;
        int expectedDecision = AccessDecisionVoter.ACCESS_GRANTED;
        doTestScopeSelfAcctPeer(otherUserRole, expectedDecision);
    }

    @Test
    public void testScopeSelfAcctPeerFail() throws DBNotFoundException {
        Role otherUserRole = Role.ROLE_USER;
        int otherAcctId = 6;
        int expectedDecision = AccessDecisionVoter.ACCESS_DENIED;
        doTestScopeSelfAcctPeer(otherUserRole, otherAcctId, expectedDecision);
    }

    @Test
    public void testScopeSelfAcctPeerFailRole() throws DBNotFoundException {
        Role otherUserRole = Role.ROLE_OWNER;
        int expectedDecision = AccessDecisionVoter.ACCESS_DENIED;
        doTestScopeSelfAcctPeer(otherUserRole, expectedDecision);
    }

    private void doTestScopeSelfAcctPeer(Role otherUserRole, int expectedDecision) throws DBNotFoundException {
        doTestScopeSelfAcctPeer(otherUserRole, -1, expectedDecision);
    }

    private void doTestScopeSelfAcctPeer(Role otherUserRole, int argAcctId, int expectedDecision)
            throws DBNotFoundException {
        Role userRole = Role.ROLE_ADMIN;

        Long userId = 3L;
        Long acctId = 5L;
        Long otherUserId = 6L;
        Long otherAcctId = argAcctId >= 0 ? argAcctId : acctId;

        AccountInfo accountInfo = new AccountInfo();
        accountInfo.setId(acctId);
        DuracloudUser user = new DuracloudUser();
        user.setId(userId);
        AccountRights rights = new AccountRights();
        rights.setAccount(accountInfo);
        rights.setUser(user);
        rights.setRoles(userRole.getRoleHierarchy());

        AccountInfo otherAccountInfo = new AccountInfo();
        otherAccountInfo.setId(otherAcctId);
        DuracloudUser otherUser = new DuracloudUser();
        otherUser.setId(otherUserId);
        AccountRights otherRights = new AccountRights();
        otherRights.setAccount(otherAccountInfo);
        otherRights.setUser(otherUser);
        otherRights.setRoles(otherUserRole.getRoleHierarchy());

        authentication = createAuthentication(rights.getUser().getId(), rights.getRoles());
        invocation = createInvocation(otherRights.getAccount().getId(), otherRights.getUser().getId(), null);
        securityConfig = createSecurityConfig(SecuredRule.Scope.SELF_ACCT_PEER);

        List<AccountRights> rightsList = new ArrayList<AccountRights>();
        rightsList.add(rights);
        rightsList.add(otherRights);
        repoMgr = createRepoMgr(rights, otherRights);

        doTest(expectedDecision);
    }

    @Test
    public void testScopeSelfAcctPeerUpdate() throws DBNotFoundException {
        Role otherUserRole = Role.ROLE_USER;
        int expectedDecision = AccessDecisionVoter.ACCESS_GRANTED;
        doTestScopeSelfAcctPeerUpdate(otherUserRole, expectedDecision);
    }

    @Test
    public void testScopeSelfAcctPeerUpdateFail() throws DBNotFoundException {
        Role otherUserRole = Role.ROLE_USER;
        int otherAcctId = 6;
        int expectedDecision = AccessDecisionVoter.ACCESS_DENIED;
        doTestScopeSelfAcctPeerUpdate(otherUserRole, null, otherAcctId, expectedDecision);
    }

    @Test
    public void testScopeSelfAcctPeerUpdateFailRole() throws DBNotFoundException {
        Role otherUserRole = Role.ROLE_OWNER;
        int expectedDecision = AccessDecisionVoter.ACCESS_DENIED;
        doTestScopeSelfAcctPeerUpdate(otherUserRole, expectedDecision);
    }

    @Test
    public void testScopeSelfAcctPeerUpdateFailNewRole() throws DBNotFoundException {
        Role otherUserRole = Role.ROLE_ADMIN;
        Set<Role> argRoles = Role.ROLE_OWNER.getRoleHierarchy();
        int expectedDecision = AccessDecisionVoter.ACCESS_DENIED;
        doTestScopeSelfAcctPeerUpdate(otherUserRole, argRoles, -1, expectedDecision);
    }

    private void doTestScopeSelfAcctPeerUpdate(Role otherUserRole, int expectedDecision)
            throws DBNotFoundException {
        doTestScopeSelfAcctPeerUpdate(otherUserRole, null, -1, expectedDecision);
    }

    private void doTestScopeSelfAcctPeerUpdate(Role otherUserRole, Set<Role> argRoles, int argAcctId,
            int expectedDecision) throws DBNotFoundException {
        Role userRole = Role.ROLE_ADMIN;

        Long userId = 3L;
        Long acctId = 5L;
        Long otherUserId = 6L;
        Long otherAcctId = argAcctId >= 0 ? argAcctId : acctId;

        AccountInfo accountInfo = new AccountInfo();
        accountInfo.setId(acctId);
        DuracloudUser user = new DuracloudUser();
        user.setId(userId);
        AccountRights rights = new AccountRights();
        rights.setAccount(accountInfo);
        rights.setUser(user);
        rights.setRoles(userRole.getRoleHierarchy());

        AccountInfo otherAccountInfo = new AccountInfo();
        otherAccountInfo.setId(otherAcctId);
        DuracloudUser otherUser = new DuracloudUser();
        otherUser.setId(otherUserId);
        AccountRights otherRights = new AccountRights();
        otherRights.setAccount(otherAccountInfo);
        otherRights.setUser(otherUser);
        otherRights.setRoles(otherUserRole.getRoleHierarchy());

        Set<Role> newArgRoles = null == argRoles ? otherUserRole.getRoleHierarchy() : argRoles;

        authentication = createAuthentication(rights.getUser().getId(), rights.getRoles());
        invocation = createInvocation(otherRights.getAccount().getId(), otherRights.getUser().getId(), null,
                newArgRoles);
        securityConfig = createSecurityConfig(SecuredRule.Scope.SELF_ACCT_PEER_UPDATE);

        List<AccountRights> rightsList = new ArrayList<AccountRights>();
        rightsList.add(rights);
        rightsList.add(otherRights);
        repoMgr = createRepoMgr(rights, otherRights);

        doTest(expectedDecision);
    }

    @Test
    public void testScopeSelf() throws DBNotFoundException {
        Role userRole = accessRole;
        int expectedDecision = AccessDecisionVoter.ACCESS_GRANTED;
        doTestScopeSelf(userRole, expectedDecision);
    }

    @Test
    public void testScopeSelfFailRole() throws DBNotFoundException {
        Role userRole = badRole;
        int expectedDecision = AccessDecisionVoter.ACCESS_DENIED;
        doTestScopeSelf(userRole, expectedDecision);
    }

    @Test
    public void testScopeSelfFailId() throws DBNotFoundException {
        Role userRole = accessRole;
        int expectedDecision = AccessDecisionVoter.ACCESS_DENIED;
        int targetUserId = 99;
        doTestScopeSelf(userRole, expectedDecision, targetUserId);
    }

    private void doTestScopeSelf(Role userRole, int expectedDecision) {
        doTestScopeSelf(userRole, expectedDecision, -1);
    }

    private void doTestScopeSelf(Role userRole, int expectedDecision, int targetId) {
        Long acctId = -1L;
        Long userId = 5L;
        Long targetUserId = targetId > -1 ? targetId : userId;
        String username = null;
        authentication = createAuthentication(userId, userRole.getRoleHierarchy());
        invocation = createInvocation(acctId, userRole.equals(accessRole) ? targetUserId : -1, username);
        securityConfig = createSecurityConfig(SecuredRule.Scope.SELF_ID);

        doTest(expectedDecision);
    }

    @Test
    public void testScopeSelfName() throws DBNotFoundException {
        Role userRole = accessRole;
        int expectedDecision = AccessDecisionVoter.ACCESS_GRANTED;
        doTestScopeSelfName(userRole, expectedDecision);
    }

    @Test
    public void testScopeSelfNameFailRole() throws DBNotFoundException {
        Role userRole = badRole;
        int expectedDecision = AccessDecisionVoter.ACCESS_DENIED;
        doTestScopeSelfName(userRole, expectedDecision);
    }

    @Test
    public void testScopeSelfNameFailName() throws DBNotFoundException {
        Role userRole = accessRole;
        int expectedDecision = AccessDecisionVoter.ACCESS_DENIED;
        String targetUsername = "bad-username";
        doTestScopeSelfName(userRole, expectedDecision, targetUsername);
    }

    private void doTestScopeSelfName(Role userRole, int expectedDecision) {
        doTestScopeSelfName(userRole, expectedDecision, null);
    }

    private void doTestScopeSelfName(Role userRole, int expectedDecision, String targetName) {
        Long acctId = -1L;
        Long userId = -1L;
        String username = "good-username";
        String targetUserName = targetName != null ? targetName : username;
        authentication = createAuthentication(userId, username, userRole.getRoleHierarchy());
        invocation = createInvocation(acctId, userId, targetUserName);
        securityConfig = createSecurityConfig(SecuredRule.Scope.SELF_NAME);

        doTest(expectedDecision);
    }

    /**
     * Mocks created below.
     */

    private DuracloudRepoMgr createRepoMgr(AccountRights rights, AccountRights otherRights)
            throws DBNotFoundException {
        DuracloudRepoMgr mgr = EasyMock.createMock("DuracloudRepoMgr", DuracloudRepoMgr.class);
        DuracloudRightsRepo rightsRepo = EasyMock.createMock("DuracloudRightsRepo", DuracloudRightsRepo.class);

        Long argAcctId = otherRights.getAccount().getId();
        if (rights.getAccount().getId() == otherRights.getAccount().getId()) {
            // This is the case when the calling user has rights on the acct.
            EasyMock.expect(rightsRepo.findByAccountIdAndUserId(argAcctId, rights.getUser().getId()))
                    .andReturn(rights).times(2);
            EasyMock.expect(rightsRepo.findByAccountIdAndUserId(argAcctId, otherRights.getUser().getId()))
                    .andReturn(otherRights);

        } else {
            // This is the case when the calling user does NOT have rights on the acct.
            EasyMock.expect(rightsRepo.findByAccountIdAndUserId(argAcctId, rights.getUser().getId()))
                    .andReturn(null);
        }

        EasyMock.expect(mgr.getRightsRepo()).andReturn(rightsRepo).atLeastOnce();

        EasyMock.replay(rightsRepo);
        return mgr;
    }

    private Authentication createAuthentication(Long userId, Set<Role> roles) {
        return createAuthentication(userId, "username", roles);
    }

    private Authentication createAuthentication(Long userId, String username, Set<Role> roles) {
        Authentication auth = EasyMock.createMock("Authentication", Authentication.class);
        DuracloudUser user = new DuracloudUser();
        user.setId(userId);
        user.setUsername(username);
        user.setPassword("password");
        user.setFirstName("firstName");
        user.setLastName("lastName");
        user.setEmail("email");
        user.setSecurityQuestion("question");
        user.setSecurityAnswer("answer");

        EasyMock.expect(auth.getPrincipal()).andReturn(user);

        Collection<GrantedAuthority> userRoles = new HashSet<GrantedAuthority>();
        for (Role role : roles) {
            userRoles.add(new SimpleGrantedAuthority(role.name()));
        }
        EasyMock.expect(auth.getAuthorities()).andReturn((Collection) userRoles);

        return auth;
    }

    private MethodInvocation createInvocation(Long acctId, Long userId, String username) {
        return createInvocation(acctId, userId, username, null);
    }

    private MethodInvocation createInvocation(Long acctId, Long userId, String username, Set<Role> roles) {
        MethodInvocation inv = EasyMock.createMock("MethodInvocation", MethodInvocation.class);

        EasyMock.expect(inv.getMethod()).andReturn(this.getClass().getMethods()[0]);

        DuracloudUserServiceImpl serviceImpl = new DuracloudUserServiceImpl(null, null, null, null);

        EasyMock.expect(inv.getThis()).andReturn(serviceImpl).times(2);

        List<Object> argList = new ArrayList<Object>();
        if (acctId >= 0) {
            argList.add(acctId);
        }

        if (userId >= 0) {
            argList.add(userId);
        }

        if (null != username) {
            argList.add(username);
        }

        if (null != roles) {
            argList.add(roles.toArray());
        }

        EasyMock.expect(inv.getArguments()).andReturn(argList.toArray());
        return inv;
    }

    private Collection<ConfigAttribute> createSecurityConfig(SecuredRule.Scope scope) {
        Collection<ConfigAttribute> attributes = new HashSet<ConfigAttribute>();

        ConfigAttribute att = new SecurityConfig("role:" + accessRole.name() + ",scope:" + scope.name());
        attributes.add(att);

        return attributes;
    }

    private void replayMocks() {
        EasyMock.replay(authentication, repoMgr, invocation);
    }

}