Package com.cedarsolutions.wiring.gae.security

Source Code of com.cedarsolutions.wiring.gae.security.GaeAuthenticationFilterTest$AuthenticationAnswer

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
*              C E D A R
*          S O L U T I O N S       "Software done right."
*           S O F T W A R E
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright (c) 2013-2014 Kenneth J. Pronovici.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Apache License, Version 2.0.
* See LICENSE for more information about the licensing terms.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Author   : Kenneth J. Pronovici <pronovic@ieee.org>
* Language : Java 6
* Project  : Common Java Functionality
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package com.cedarsolutions.wiring.gae.security;

import static com.cedarsolutions.wiring.gae.security.GaeAuthenticationFilter.CLIENT_ROLES_ATTRIBUTE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationManager;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.context.SecurityContext;

import com.cedarsolutions.exception.NotConfiguredException;
import com.cedarsolutions.exception.NotImplementedException;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;

/**
* Unit tests for GaeAuthenticationFilter.
* @author Kenneth J. Pronovici <pronovic@ieee.org>
*/
public class GaeAuthenticationFilterTest {

    /** Test the constructor. */
    @Test public void testConstructor() {
        GaeAuthenticationFilter filter = new GaeAuthenticationFilter();
        assertNotNull(filter);
        assertNull(filter.getUserService());
        assertNull(filter.getAuthenticationManager());
        assertNull(filter.getFilterConfig());
    }

    /** Test the getters and setters. */
    @Test public void testGettersSetters() {
        UserService userService = mock(UserService.class);
        AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
        GaeAuthenticationFilter filter = new GaeAuthenticationFilter();

        filter.setUserService(userService);
        assertSame(userService, filter.getUserService());

        filter.setAuthenticationManager(authenticationManager);
        assertSame(authenticationManager, filter.getAuthenticationManager());
    }

    /** Test afterPropertiesSet(). */
    @Test public void testAfterPropertiesSet() {
        UserService userService = mock(UserService.class);
        AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
        GaeAuthenticationFilter filter = new GaeAuthenticationFilter();

        try {
            filter.setUserService(null);
            filter.setAuthenticationManager(authenticationManager);
            filter.afterPropertiesSet();
            fail("Expected NotConfiguredException");
        } catch (NotConfiguredException e) { }

        try {
            filter.setUserService(userService);
            filter.setAuthenticationManager(null);
            filter.afterPropertiesSet();
            fail("Expected NotConfiguredException");
        } catch (NotConfiguredException e) { }

        filter.setUserService(userService);
        filter.setAuthenticationManager(authenticationManager);
        filter.afterPropertiesSet();
    }

    /** Test doFilter() when the user is not logged in. */
    @Test public void testDoFilterAnonymous() throws Exception {
        UserService userService = mock(UserService.class);
        AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
        StubbedGaeAuthenticationFilter filter = new StubbedGaeAuthenticationFilter();

        filter.setUserService(userService);
        filter.setAuthenticationManager(authenticationManager);
        filter.afterPropertiesSet();

        when(authenticationManager.authenticate(isA(GaeUserAuthenticationToken.class))).thenAnswer(new AuthenticationAnswer());
        when(userService.isUserLoggedIn()).thenReturn(false);     // user is not logged in

        GaeUser gaeUser = callDoFilter(filter)// no client roles
        assertEquals("", gaeUser.getAuthDomain());
        assertEquals("", gaeUser.getFederatedIdentity());
        assertEquals("", gaeUser.getEmail());
        assertEquals(GaeUser.ANONYMOUS_USER_ID, gaeUser.getUserId());
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_ANONYMOUS));
        assertFalse(gaeUser.getRoles().contains(GaeRole.ROLE_USER));
        assertFalse(gaeUser.getRoles().contains(GaeRole.ROLE_ADMIN));
        assertTrue(gaeUser.isAnonymous());
        assertFalse(gaeUser.isAdmin());
    }

    /** Test doFilter() when the user is not logged in, with client roles set. */
    @Test public void testDoFilterAnonymousWithClientRoles() throws Exception {
        UserService userService = mock(UserService.class);
        AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
        StubbedGaeAuthenticationFilter filter = new StubbedGaeAuthenticationFilter();

        filter.setUserService(userService);
        filter.setAuthenticationManager(authenticationManager);
        filter.afterPropertiesSet();

        when(authenticationManager.authenticate(isA(GaeUserAuthenticationToken.class))).thenAnswer(new AuthenticationAnswer());
        when(userService.isUserLoggedIn()).thenReturn(false);     // user is not logged in

        GaeUser gaeUser = callDoFilter(filter, "ONE");
        assertEquals("", gaeUser.getAuthDomain());
        assertEquals("", gaeUser.getFederatedIdentity());
        assertEquals("", gaeUser.getEmail());
        assertEquals(GaeUser.ANONYMOUS_USER_ID, gaeUser.getUserId());
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_ANONYMOUS));
        assertFalse(gaeUser.getRoles().contains(GaeRole.ROLE_USER));
        assertFalse(gaeUser.getRoles().contains(GaeRole.ROLE_ADMIN));
        assertFalse(gaeUser.getRoles().contains(new GaeRole("ONE")));
        assertTrue(gaeUser.isAnonymous());
        assertFalse(gaeUser.isAdmin());
    }

    /** Test doFilter() when the user is logged in and is not an admin user. */
    @Test public void testDoFilterLoggedIn() throws Exception {
        UserService userService = mock(UserService.class);
        AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
        StubbedGaeAuthenticationFilter filter = new StubbedGaeAuthenticationFilter();

        filter.setUserService(userService);
        filter.setAuthenticationManager(authenticationManager);
        filter.afterPropertiesSet();

        User user = new User("email", "authDomain", "userId", "federatedIdentity");
        when(authenticationManager.authenticate(isA(GaeUserAuthenticationToken.class))).thenAnswer(new AuthenticationAnswer());
        when(userService.isUserLoggedIn()).thenReturn(true);      // user is logged in
        when(userService.isUserAdmin()).thenReturn(false);        // user is not an admin
        when(userService.getCurrentUser()).thenReturn(user);      // this is the logged in user

        GaeUser gaeUser = callDoFilter(filter)// no client roles
        assertEquals(user.getAuthDomain(), gaeUser.getAuthDomain());
        assertEquals(user.getFederatedIdentity(), gaeUser.getFederatedIdentity());
        assertEquals(user.getEmail(), gaeUser.getEmail());
        assertEquals(user.getUserId(), gaeUser.getUserId());
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_ANONYMOUS));
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_USER));
        assertFalse(gaeUser.getRoles().contains(GaeRole.ROLE_ADMIN));
        assertFalse(gaeUser.isAnonymous());
        assertFalse(gaeUser.isAdmin());
    }

    /** Test doFilter() when the user is logged in and is not an admin user, with client roles. */
    @Test public void testDoFilterLoggedInWithClientRoles() throws Exception {
        UserService userService = mock(UserService.class);
        AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
        StubbedGaeAuthenticationFilter filter = new StubbedGaeAuthenticationFilter();

        filter.setUserService(userService);
        filter.setAuthenticationManager(authenticationManager);
        filter.afterPropertiesSet();

        User user = new User("email", "authDomain", "userId", "federatedIdentity");
        when(authenticationManager.authenticate(isA(GaeUserAuthenticationToken.class))).thenAnswer(new AuthenticationAnswer());
        when(userService.isUserLoggedIn()).thenReturn(true);      // user is logged in
        when(userService.isUserAdmin()).thenReturn(false);        // user is not an admin
        when(userService.getCurrentUser()).thenReturn(user);      // this is the logged in user

        GaeUser gaeUser = callDoFilter(filter, "ONE");
        assertEquals(user.getAuthDomain(), gaeUser.getAuthDomain());
        assertEquals(user.getFederatedIdentity(), gaeUser.getFederatedIdentity());
        assertEquals(user.getEmail(), gaeUser.getEmail());
        assertEquals(user.getUserId(), gaeUser.getUserId());
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_ANONYMOUS));
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_USER));
        assertFalse(gaeUser.getRoles().contains(GaeRole.ROLE_ADMIN));
        assertTrue(gaeUser.getRoles().contains(new GaeRole("ONE")));
        assertFalse(gaeUser.isAnonymous());
        assertFalse(gaeUser.isAdmin());
    }

    /** Test doFilter() when the user is logged in and is an admin user. */
    @Test public void testDoFilterAdmin() throws Exception {
        UserService userService = mock(UserService.class);
        AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
        StubbedGaeAuthenticationFilter filter = new StubbedGaeAuthenticationFilter();

        filter.setUserService(userService);
        filter.setAuthenticationManager(authenticationManager);
        filter.afterPropertiesSet();

        User user = new User("email", "authDomain", "userId", "federatedIdentity");
        when(authenticationManager.authenticate(isA(GaeUserAuthenticationToken.class))).thenAnswer(new AuthenticationAnswer());
        when(userService.isUserLoggedIn()).thenReturn(true);      // user is logged in
        when(userService.isUserAdmin()).thenReturn(true);         // user is an admin
        when(userService.getCurrentUser()).thenReturn(user);      // this is the logged in user

        GaeUser gaeUser = callDoFilter(filter)// no client roles
        assertEquals(user.getAuthDomain(), gaeUser.getAuthDomain());
        assertEquals(user.getFederatedIdentity(), gaeUser.getFederatedIdentity());
        assertEquals(user.getEmail(), gaeUser.getEmail());
        assertEquals(user.getUserId(), gaeUser.getUserId());
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_ANONYMOUS));
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_USER));
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_ADMIN));
        assertFalse(gaeUser.isAnonymous());
        assertTrue(gaeUser.isAdmin());
    }

    /** Test doFilter() when the user is logged in and is an admin user, with client roles. */
    @Test public void testDoFilterAdminWithClientRoles() throws Exception {
        UserService userService = mock(UserService.class);
        AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
        StubbedGaeAuthenticationFilter filter = new StubbedGaeAuthenticationFilter();

        filter.setUserService(userService);
        filter.setAuthenticationManager(authenticationManager);
        filter.afterPropertiesSet();

        User user = new User("email", "authDomain", "userId", "federatedIdentity");
        when(authenticationManager.authenticate(isA(GaeUserAuthenticationToken.class))).thenAnswer(new AuthenticationAnswer());
        when(userService.isUserLoggedIn()).thenReturn(true);      // user is logged in
        when(userService.isUserAdmin()).thenReturn(true);         // user is an admin
        when(userService.getCurrentUser()).thenReturn(user);      // this is the logged in user

        GaeUser gaeUser = callDoFilter(filter, "ONE");
        assertEquals(user.getAuthDomain(), gaeUser.getAuthDomain());
        assertEquals(user.getFederatedIdentity(), gaeUser.getFederatedIdentity());
        assertEquals(user.getEmail(), gaeUser.getEmail());
        assertEquals(user.getUserId(), gaeUser.getUserId());
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_ANONYMOUS));
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_USER));
        assertTrue(gaeUser.getRoles().contains(GaeRole.ROLE_ADMIN));
        assertTrue(gaeUser.getRoles().contains(new GaeRole("ONE")));
        assertFalse(gaeUser.isAnonymous());
        assertTrue(gaeUser.isAdmin());
    }

    /** Call doFilter(), returning the user that was authenticated. */
    private static GaeUser callDoFilter(StubbedGaeAuthenticationFilter filter, String ... clientRoles) throws Exception {
        HttpServletRequest request = mock(HttpServletRequest.class);
        HttpServletResponse response = mock(HttpServletResponse.class);
        FilterChain chain = mock(FilterChain.class);
        HttpSession session = mock(HttpSession.class);

        when(session.getAttribute(CLIENT_ROLES_ATTRIBUTE)).thenReturn(clientRoles);
        when(request.getSession(false)).thenReturn(session);

        filter.doFilter(request, response, chain);

        Authentication authentication = filter.getMockSecurityContext().getAuthentication();
        assertNotNull(authentication);
        assertTrue(authentication instanceof StubbedAuthentication);
        GaeUserAuthenticationToken token = ((StubbedAuthentication) authentication).getToken();
        assertNotNull(token.getDetails())// don't care exactly what's in it, just that it's filled in
        assertTrue(token.getPrincipal() instanceof GaeUser);

        return (GaeUser) token.getPrincipal();
    }

    /**
     * Mockito answer to give back the proper response to a GaeUserAuthenticationToken.
     * @see <a href="http://stackoverflow.com/questions/2684630/mockito-how-to-make-a-method-return-an-argument-that-was-passed-to-it">Stack Overflow</a>
     */
    private static class AuthenticationAnswer implements Answer<Authentication> {
        @Override
        public Authentication answer(InvocationOnMock invocation) throws Throwable {
            Object[] args = invocation.getArguments();
            GaeUserAuthenticationToken token = (GaeUserAuthenticationToken) args[0];
            return new StubbedAuthentication(token);
        }
    }

    /**
     * Stubbed GaeAuthenticationFilter for testing.
     * This class lets us override the security context so we can introspect it.
     */
    private static class StubbedGaeAuthenticationFilter extends GaeAuthenticationFilter {
        private MockSecurityContext mockSecurityContext;

        public StubbedGaeAuthenticationFilter() {
            this.mockSecurityContext = new MockSecurityContext();
        }

        @Override
        protected SecurityContext getSecurityContext() {
            return this.mockSecurityContext;
        }

        public MockSecurityContext getMockSecurityContext() {
            return this.mockSecurityContext;
        }
    }

    /** Mock security context class. */
    @SuppressWarnings("serial")
    private static class MockSecurityContext implements SecurityContext {

        private Authentication authentication;

        @Override
        public Authentication getAuthentication() {
            return this.authentication;
        }

        @Override
        public void setAuthentication(Authentication authentication) {
            this.authentication = authentication;
        }
    }

    /** Stubbed authentication object that we can use to verify behavior. */
    @SuppressWarnings("serial")
    private static class StubbedAuthentication implements Authentication {

        private GaeUserAuthenticationToken token;

        public StubbedAuthentication(GaeUserAuthenticationToken token) {
            this.token = token;
        }

        public GaeUserAuthenticationToken getToken() {
            return this.token;
        }

        @Override
        public String getName() {
            throw new NotImplementedException("StubbedAuthentication");
        }

        @Override
        public GrantedAuthority[] getAuthorities() {
            throw new NotImplementedException("StubbedAuthentication");
        }

        @Override
        public Object getCredentials() {
            throw new NotImplementedException("StubbedAuthentication");
        }

        @Override
        public Object getDetails() {
            throw new NotImplementedException("StubbedAuthentication");
        }

        @Override
        public Object getPrincipal() {
            throw new NotImplementedException("StubbedAuthentication");
        }

        @Override
        public boolean isAuthenticated() {
            throw new NotImplementedException("StubbedAuthentication");
        }

        @Override
        public void setAuthenticated(boolean arg0) throws IllegalArgumentException {
            throw new NotImplementedException("StubbedAuthentication");
        }
    }
}
TOP

Related Classes of com.cedarsolutions.wiring.gae.security.GaeAuthenticationFilterTest$AuthenticationAnswer

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.