/**
* Copyright 2017 Linagora, Université Joseph Fourier, Floralis
*
* The present code is developed in the scope of the joint LINAGORA -
* Université Joseph Fourier - Floralis research program and is designated
* as a "Result" pursuant to the terms and conditions of the LINAGORA
* - Université Joseph Fourier - Floralis research program. Each copyright
* holder of Results enumerated here above fully & independently holds complete
* ownership of the complete Intellectual Property rights applicable to the whole
* of said Results, and may freely exploit it in any manner which does not infringe
* the moral rights of the other copyright holders.
*
* Licensed 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 net.roboconf.dm.rest.services.internal.filters;
import static net.roboconf.dm.rest.services.internal.ServletRegistrationComponent.REST_CONTEXT;
import static net.roboconf.dm.rest.services.internal.ServletRegistrationComponent.WEBSOCKET_CONTEXT;
import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
import net.roboconf.dm.management.api.IPreferencesMngr;
import net.roboconf.dm.rest.commons.UrlConstants;
import net.roboconf.dm.rest.commons.security.AuthenticationManager;
import net.roboconf.dm.rest.services.cors.ResponseCorsFilter;
import net.roboconf.dm.rest.services.internal.resources.IAuthenticationResource;
import net.roboconf.dm.rest.services.internal.resources.IPreferencesResource;
/**
* @author Vincent Zurczak - Linagora
*/
public class AuthenticationFilterTest {
@Test
public void forCodeCoverage() throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
filter.init( null );
filter.destroy();
}
@Test
public void testDoFiler_noAuthentication() throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationEnabled( false );
ServletRequest req = Mockito.mock( ServletRequest.class );
ServletResponse resp = Mockito.mock( ServletResponse.class );
FilterChain chain = Mockito.mock( FilterChain.class );
filter.doFilter( req, resp, chain );
Mockito.verifyZeroInteractions( req );
Mockito.verifyZeroInteractions( resp );
Mockito.verify( chain, Mockito.only()).doFilter( req, resp );
}
@Test
public void testDoFiler_withAuthentication_noCookie() throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationEnabled( true );
filter.setAuthenticationManager( Mockito.mock( AuthenticationManager.class ));
HttpServletRequest req = Mockito.mock( HttpServletRequest.class );
Mockito.when( req.getRequestURI()).thenReturn( "/whatever" );
HttpServletResponse resp = Mockito.mock( HttpServletResponse.class );
FilterChain chain = Mockito.mock( FilterChain.class );
filter.doFilter( req, resp, chain );
Mockito.verify( req ).getCookies();
Mockito.verify( req, Mockito.times( 2 )).getRequestURI();
Mockito.verify( req, Mockito.times( 2 )).getMethod();
Mockito.verify( req ).getRemoteAddr();
Mockito.verify( req ).getQueryString();
Mockito.verify( req ).getHeader( AuthenticationFilter.USER_AGENT );
Mockito.verifyNoMoreInteractions( req );
Mockito.verify( resp, Mockito.only()).sendError( 403, "Authentication is required." );
Mockito.verifyNoMoreInteractions( resp );
Mockito.verifyZeroInteractions( chain );
}
@Test
public void testDoFiler_withAuthentication_noCookie_corsEnabled() throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationEnabled( true );
filter.setAuthenticationManager( Mockito.mock( AuthenticationManager.class ));
filter.setEnableCors( true );
HttpServletRequest req = Mockito.mock( HttpServletRequest.class );
Mockito.when( req.getRequestURI()).thenReturn( "/whatever" );
HttpServletResponse resp = Mockito.mock( HttpServletResponse.class );
FilterChain chain = Mockito.mock( FilterChain.class );
filter.doFilter( req, resp, chain );
Mockito.verify( req ).getCookies();
Mockito.verify( req, Mockito.times( 2 )).getRequestURI();
Mockito.verify( req, Mockito.times( 2 )).getMethod();
Mockito.verify( req ).getRemoteAddr();
Mockito.verify( req ).getQueryString();
Mockito.verify( req ).getHeader( ResponseCorsFilter.CORS_REQ_HEADERS );
Mockito.verify( req ).getHeader( ResponseCorsFilter.ORIGIN );
Mockito.verify( req ).getHeader( AuthenticationFilter.USER_AGENT );
Mockito.verifyNoMoreInteractions( req );
Mockito.verify( resp, Mockito.times( 3 )).setHeader( Mockito.anyString(), Mockito.anyString());
Mockito.verify( resp ).sendError( 403, "Authentication is required." );
Mockito.verifyNoMoreInteractions( resp );
Mockito.verifyZeroInteractions( chain );
}
@Test
public void testDoFiler_withAuthentication_withCookie_loggedIn() throws Exception {
final String sessionId = "a1a2a3a4";
final long sessionPeriod = -1;
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationEnabled( true );
filter.setSessionPeriod( sessionPeriod );
AuthenticationManager authMngr = Mockito.mock( AuthenticationManager.class );
Mockito.when( authMngr.isSessionValid( sessionId, sessionPeriod )).thenReturn( true );
filter.setAuthenticationManager( authMngr );
FilterChain chain = Mockito.mock( FilterChain.class );
HttpServletResponse resp = Mockito.mock( HttpServletResponse.class );
HttpServletRequest req = Mockito.mock( HttpServletRequest.class );
Mockito.when( req.getRequestURI()).thenReturn( "/whatever" );
Mockito.when( req.getCookies()).thenReturn( new Cookie[] {
new Cookie( "as", "as" ),
new Cookie( UrlConstants.SESSION_ID, sessionId )
});
filter.doFilter( req, resp, chain );
Mockito.verify( req ).getCookies();
Mockito.verify( req, Mockito.times( 2 )).getRequestURI();
Mockito.verify( req, Mockito.times( 2 )).getMethod();
Mockito.verify( req ).getRemoteAddr();
Mockito.verify( req ).getQueryString();
Mockito.verify( req ).getHeader( AuthenticationFilter.USER_AGENT );
Mockito.verifyNoMoreInteractions( req );
Mockito.verify( authMngr ).isSessionValid( sessionId, sessionPeriod );
Mockito.verify( chain, Mockito.only()).doFilter( req, resp );
Mockito.verifyZeroInteractions( resp );
}
@Test
public void testDoFiler_withAuthentication_withCookie_notLoggedIn() throws Exception {
final String sessionId = "a1a2a3a4";
final long sessionPeriod = -1;
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationEnabled( true );
filter.setSessionPeriod( sessionPeriod );
AuthenticationManager authMngr = Mockito.mock( AuthenticationManager.class );
Mockito.when( authMngr.isSessionValid( sessionId, sessionPeriod )).thenReturn( false );
filter.setAuthenticationManager( authMngr );
FilterChain chain = Mockito.mock( FilterChain.class );
HttpServletResponse resp = Mockito.mock( HttpServletResponse.class );
HttpServletRequest req = Mockito.mock( HttpServletRequest.class );
Mockito.when( req.getRequestURI()).thenReturn( "/whatever" );
Mockito.when( req.getCookies()).thenReturn( new Cookie[] {
new Cookie( "as", "as" ),
new Cookie( UrlConstants.SESSION_ID, sessionId )
});
filter.doFilter( req, resp, chain );
Mockito.verify( req ).getCookies();
Mockito.verify( req, Mockito.times( 2 )).getRequestURI();
Mockito.verify( req, Mockito.times( 2 )).getMethod();
Mockito.verify( req ).getRemoteAddr();
Mockito.verify( req ).getQueryString();
Mockito.verify( req ).getHeader( AuthenticationFilter.USER_AGENT );
Mockito.verifyNoMoreInteractions( req );
Mockito.verify( authMngr ).isSessionValid( sessionId, sessionPeriod );
Mockito.verifyZeroInteractions( chain );
Mockito.verify( resp, Mockito.only()).sendError( 403, "Authentication is required." );
}
@Test
public void testDoFiler_withAuthentication_noCookie_butLoginPageRequested() throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationEnabled( true );
filter.setAuthenticationManager( Mockito.mock( AuthenticationManager.class ));
HttpServletRequest req = Mockito.mock( HttpServletRequest.class );
Mockito.when( req.getRequestURI()).thenReturn( IAuthenticationResource.PATH + IAuthenticationResource.LOGIN_PATH );
Mockito.when( req.getCookies()).thenReturn( new Cookie[ 0 ]);
Mockito.when( req.getMethod()).thenReturn( "poSt" );
HttpServletResponse resp = Mockito.mock( HttpServletResponse.class );
FilterChain chain = Mockito.mock( FilterChain.class );
filter.doFilter( req, resp, chain );
Mockito.verify( req ).getCookies();
Mockito.verify( req, Mockito.times( 2 )).getRequestURI();
Mockito.verify( req, Mockito.times( 2 )).getMethod();
Mockito.verify( req ).getRemoteAddr();
Mockito.verify( req ).getQueryString();
Mockito.verify( req ).getHeader( AuthenticationFilter.USER_AGENT );
Mockito.verifyNoMoreInteractions( req );
Mockito.verify( chain, Mockito.only()).doFilter( req, resp );
Mockito.verifyZeroInteractions( resp );
}
@Test
public void testDoFiler_withAuthentication_noCookie_butUserPrefRequested() throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationEnabled( true );
filter.setAuthenticationManager( Mockito.mock( AuthenticationManager.class ));
HttpServletRequest req = Mockito.mock( HttpServletRequest.class );
Mockito.when( req.getRequestURI()).thenReturn( IPreferencesResource.PATH );
Mockito.when( req.getQueryString()).thenReturn( "key=" + IPreferencesMngr.USER_LANGUAGE );
Mockito.when( req.getCookies()).thenReturn( new Cookie[ 0 ]);
Mockito.when( req.getMethod()).thenReturn( "Get" );
HttpServletResponse resp = Mockito.mock( HttpServletResponse.class );
FilterChain chain = Mockito.mock( FilterChain.class );
filter.doFilter( req, resp, chain );
Mockito.verify( req ).getCookies();
Mockito.verify( req, Mockito.times( 2 )).getRequestURI();
Mockito.verify( req, Mockito.times( 2 )).getMethod();
Mockito.verify( req ).getRemoteAddr();
Mockito.verify( req, Mockito.times( 2 )).getQueryString();
Mockito.verify( req ).getHeader( AuthenticationFilter.USER_AGENT );
Mockito.verifyNoMoreInteractions( req );
Mockito.verify( chain, Mockito.only()).doFilter( req, resp );
Mockito.verifyZeroInteractions( resp );
}
@Test
public void testDoFiler_withAuthentication_noCookie_butOptionsRequest() throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationEnabled( true );
filter.setAuthenticationManager( Mockito.mock( AuthenticationManager.class ));
HttpServletRequest req = Mockito.mock( HttpServletRequest.class );
Mockito.when( req.getRequestURI()).thenReturn( IPreferencesResource.PATH );
Mockito.when( req.getCookies()).thenReturn( new Cookie[ 0 ]);
Mockito.when( req.getMethod()).thenReturn( "opTions" );
HttpServletResponse resp = Mockito.mock( HttpServletResponse.class );
FilterChain chain = Mockito.mock( FilterChain.class );
filter.doFilter( req, resp, chain );
Mockito.verify( req ).getCookies();
Mockito.verify( req, Mockito.times( 2 )).getRequestURI();
Mockito.verify( req, Mockito.times( 2 )).getMethod();
Mockito.verify( req ).getRemoteAddr();
Mockito.verify( req ).getQueryString();
Mockito.verify( req ).getHeader( AuthenticationFilter.USER_AGENT );
Mockito.verifyNoMoreInteractions( req );
Mockito.verify( chain, Mockito.only()).doFilter( req, resp );
Mockito.verifyZeroInteractions( resp );
}
@Test
public void testDoFiler_withAuthentication_noCookie_butUserPrefRequested_post() throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationEnabled( true );
filter.setAuthenticationManager( Mockito.mock( AuthenticationManager.class ));
HttpServletRequest req = Mockito.mock( HttpServletRequest.class );
Mockito.when( req.getRequestURI()).thenReturn( IPreferencesResource.PATH );
Mockito.when( req.getQueryString()).thenReturn( "key=" + IPreferencesMngr.USER_LANGUAGE );
Mockito.when( req.getCookies()).thenReturn( new Cookie[ 0 ]);
Mockito.when( req.getMethod()).thenReturn( "post" );
HttpServletResponse resp = Mockito.mock( HttpServletResponse.class );
FilterChain chain = Mockito.mock( FilterChain.class );
filter.doFilter( req, resp, chain );
Mockito.verify( req ).getCookies();
Mockito.verify( req, Mockito.times( 2 )).getRequestURI();
Mockito.verify( req, Mockito.times( 2 )).getMethod();
Mockito.verify( req ).getRemoteAddr();
Mockito.verify( req ).getQueryString();
Mockito.verify( req ).getHeader( AuthenticationFilter.USER_AGENT );
Mockito.verifyNoMoreInteractions( req );
Mockito.verifyZeroInteractions( chain );
Mockito.verify( resp, Mockito.only()).sendError( 403, "Authentication is required." );
}
@Test
public void testDoFiler_withAuthentication_noCookie_butOtherPrefRequested() throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationEnabled( true );
filter.setAuthenticationManager( Mockito.mock( AuthenticationManager.class ));
HttpServletRequest req = Mockito.mock( HttpServletRequest.class );
Mockito.when( req.getRequestURI()).thenReturn( IPreferencesResource.PATH );
Mockito.when( req.getQueryString()).thenReturn( "key=whatever" );
Mockito.when( req.getCookies()).thenReturn( new Cookie[ 0 ]);
Mockito.when( req.getMethod()).thenReturn( "Get" );
HttpServletResponse resp = Mockito.mock( HttpServletResponse.class );
FilterChain chain = Mockito.mock( FilterChain.class );
filter.doFilter( req, resp, chain );
Mockito.verify( req ).getCookies();
Mockito.verify( req, Mockito.times( 2 )).getRequestURI();
Mockito.verify( req, Mockito.times( 2 )).getMethod();
Mockito.verify( req ).getRemoteAddr();
Mockito.verify( req, Mockito.times( 2 )).getQueryString();
Mockito.verify( req ).getHeader( AuthenticationFilter.USER_AGENT );
Mockito.verifyNoMoreInteractions( req );
Mockito.verifyZeroInteractions( chain );
Mockito.verify( resp, Mockito.only()).sendError( 403, "Authentication is required." );
}
@Test
public void testCleanPath() {
Assert.assertEquals( "", AuthenticationFilter.cleanPath( "" ));
Assert.assertEquals( REST_CONTEXT, AuthenticationFilter.cleanPath( REST_CONTEXT ));
Assert.assertEquals( "/", AuthenticationFilter.cleanPath( REST_CONTEXT + "/" ));
Assert.assertEquals( REST_CONTEXT, AuthenticationFilter.cleanPath( REST_CONTEXT + REST_CONTEXT ));
Assert.assertEquals( "/test", AuthenticationFilter.cleanPath( REST_CONTEXT + "/test" ));
Assert.assertEquals( WEBSOCKET_CONTEXT, AuthenticationFilter.cleanPath( WEBSOCKET_CONTEXT ));
Assert.assertEquals( "/", AuthenticationFilter.cleanPath( WEBSOCKET_CONTEXT + "/" ));
Assert.assertEquals( "/ty", AuthenticationFilter.cleanPath( WEBSOCKET_CONTEXT + "/ty" ));
Assert.assertEquals( WEBSOCKET_CONTEXT + "ty", AuthenticationFilter.cleanPath( WEBSOCKET_CONTEXT + "ty" ));
Assert.assertEquals( "/test", AuthenticationFilter.cleanPath( REST_CONTEXT + "/test?p=toto/22" ));
}
}