1 package org.apache.archiva.webdav;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import com.meterware.httpunit.GetMethodWebRequest;
23 import com.meterware.httpunit.HttpUnitOptions;
24 import com.meterware.httpunit.PutMethodWebRequest;
25 import com.meterware.httpunit.WebRequest;
26 import com.meterware.httpunit.WebResponse;
27 import com.meterware.servletunit.InvocationContext;
28 import com.meterware.servletunit.ServletRunner;
29 import com.meterware.servletunit.ServletUnitClient;
30 import junit.framework.TestCase;
31 import net.sf.ehcache.CacheManager;
32 import org.apache.archiva.redback.authentication.AuthenticationException;
33 import org.apache.archiva.redback.users.User;
34 import org.apache.archiva.repository.audit.TestAuditListener;
35 import org.apache.archiva.security.common.ArchivaRoleConstants;
36 import org.apache.commons.io.FileUtils;
37 import org.apache.jackrabbit.webdav.DavSessionProvider;
38 import org.apache.archiva.configuration.ArchivaConfiguration;
39 import org.apache.archiva.configuration.Configuration;
40 import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
41 import org.apache.archiva.security.ServletAuthenticator;
42 import org.apache.archiva.redback.authentication.AuthenticationResult;
43 import org.apache.archiva.redback.authorization.UnauthorizedException;
44 import org.apache.archiva.redback.system.DefaultSecuritySession;
45 import org.apache.archiva.redback.system.SecuritySession;
46 import org.apache.archiva.redback.users.memory.SimpleUser;
47 import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator;
48 import org.apache.archiva.redback.integration.filter.authentication.basic.HttpBasicAuthentication;
49 import org.easymock.MockControl;
50 import org.easymock.classextension.MockClassControl;
51 import org.junit.After;
52 import org.junit.Before;
53 import org.junit.Test;
54 import org.junit.runner.RunWith;
55 import org.springframework.context.ApplicationContext;
56 import org.springframework.test.context.ContextConfiguration;
58 import javax.inject.Inject;
59 import javax.servlet.http.HttpServletResponse;
61 import java.io.IOException;
62 import java.io.InputStream;
63 import java.nio.charset.Charset;
65 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
68 * RepositoryServletSecurityTest Test the flow of the authentication and authorization checks. This does not necessarily
69 * perform redback security checking.
73 @RunWith( ArchivaSpringJUnit4ClassRunner.class )
74 @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
75 public class RepositoryServletSecurityTest
78 protected static final String REPOID_INTERNAL = "internal";
80 protected ServletUnitClient sc;
82 protected File repoRootInternal;
84 private ServletRunner sr;
86 protected ArchivaConfiguration archivaConfiguration;
88 private DavSessionProvider davSessionProvider;
90 private MockControl servletAuthControl;
92 private ServletAuthenticator servletAuth;
94 private MockClassControl httpAuthControl;
96 private HttpAuthenticator httpAuth;
98 private RepositoryServlet servlet;
101 ApplicationContext applicationContext;
109 String appserverBase = System.getProperty( "appserver.base", new File( "target/appserver-base" ).getAbsolutePath() );
111 File testConf = new File( "src/test/resources/repository-archiva.xml" );
112 File testConfDest = new File( appserverBase, "conf/archiva.xml" );
113 FileUtils.copyFile( testConf, testConfDest );
115 repoRootInternal = new File( appserverBase, "data/repositories/internal" );
117 archivaConfiguration = applicationContext.getBean( ArchivaConfiguration.class );
118 Configuration config = archivaConfiguration.getConfiguration();
120 if (!config.getManagedRepositoriesAsMap().containsKey( REPOID_INTERNAL ))
122 config.addManagedRepository( createManagedRepository( REPOID_INTERNAL, "Internal Test Repo", repoRootInternal ) );
124 saveConfiguration( archivaConfiguration );
126 CacheManager.getInstance().clearAll();
128 HttpUnitOptions.setExceptionsThrownOnErrorStatus( false );
130 sr = new ServletRunner( new File( "src/test/resources/WEB-INF/repository-servlet-security-test/web.xml" ) );
131 sr.registerServlet( "/repository/*", RepositoryServlet.class.getName() );
134 servletAuthControl = MockControl.createControl( ServletAuthenticator.class );
135 servletAuthControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
136 servletAuth = (ServletAuthenticator) servletAuthControl.getMock();
139 MockClassControl.createControl( HttpBasicAuthentication.class, HttpBasicAuthentication.class.getMethods() );
140 httpAuthControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
141 httpAuth = (HttpAuthenticator) httpAuthControl.getMock();
143 davSessionProvider = new ArchivaDavSessionProvider( servletAuth, httpAuth );
146 protected ManagedRepositoryConfiguration createManagedRepository( String id, String name, File location )
148 ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration();
150 repo.setName( name );
151 repo.setLocation( location.getAbsolutePath() );
155 protected void saveConfiguration()
158 saveConfiguration( archivaConfiguration );
161 protected void saveConfiguration( ArchivaConfiguration archivaConfiguration )
164 archivaConfiguration.save( archivaConfiguration.getConfiguration() );
167 protected void setupCleanRepo( File repoRootDir )
170 FileUtils.deleteDirectory( repoRootDir );
171 if ( !repoRootDir.exists() )
173 repoRootDir.mkdirs();
179 public void tearDown()
192 if ( repoRootInternal.exists() )
194 FileUtils.deleteDirectory( repoRootInternal );
202 // test deploy with invalid user, and guest has no write access to repo
203 // 401 must be returned
205 public void testPutWithInvalidUserAndGuestHasNoWriteAccess()
208 setupCleanRepo( repoRootInternal );
210 String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
211 InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
212 assertNotNull( "artifact.jar inputstream", is );
214 WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
215 InvocationContext ic = sc.newInvocation( request );
216 servlet = (RepositoryServlet) ic.getServlet();
217 servlet.setDavSessionProvider( davSessionProvider );
219 AuthenticationResult result = new AuthenticationResult();
220 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
221 servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
222 new AuthenticationException( "Authentication error" ) );
224 servletAuth.isAuthorized( "guest", "internal", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
225 servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
226 servletAuthControl.setThrowable( new UnauthorizedException( "'guest' has no write access to repository" ) );
228 httpAuthControl.replay();
229 servletAuthControl.replay();
231 servlet.service( ic.getRequest(), ic.getResponse() );
233 httpAuthControl.verify();
234 servletAuthControl.verify();
236 // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
239 // test deploy with invalid user, but guest has write access to repo
241 public void testPutWithInvalidUserAndGuestHasWriteAccess()
244 setupCleanRepo( repoRootInternal );
246 String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
247 InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
248 assertNotNull( "artifact.jar inputstream", is );
250 WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
252 InvocationContext ic = sc.newInvocation( request );
253 servlet = (RepositoryServlet) ic.getServlet();
254 servlet.setDavSessionProvider( davSessionProvider );
256 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
257 archivaDavResourceFactory.setHttpAuth( httpAuth );
258 archivaDavResourceFactory.setServletAuth( servletAuth );
260 servlet.setResourceFactory( archivaDavResourceFactory );
262 AuthenticationResult result = new AuthenticationResult();
263 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
264 servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
265 new AuthenticationException( "Authentication error" ) );
267 servletAuth.isAuthorized( "guest", "internal", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
268 servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
269 servletAuthControl.setReturnValue( true );
271 // ArchivaDavResourceFactory#isAuthorized()
272 SecuritySession session = new DefaultSecuritySession();
273 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
274 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
275 servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, result ),
276 new AuthenticationException( "Authentication error" ) );
278 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), null );
280 // check if guest has write access
281 servletAuth.isAuthorized( "guest", "internal", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
282 servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
283 servletAuthControl.setReturnValue( true );
285 httpAuthControl.replay();
286 servletAuthControl.replay();
288 servlet.service( ic.getRequest(), ic.getResponse() );
290 httpAuthControl.verify();
291 servletAuthControl.verify();
293 // assertEquals( HttpServletResponse.SC_CREATED, response.getResponseCode() );
296 // test deploy with a valid user with no write access
298 public void testPutWithValidUserWithNoWriteAccess()
301 setupCleanRepo( repoRootInternal );
303 String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
304 InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
305 assertNotNull( "artifact.jar inputstream", is );
307 WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
309 InvocationContext ic = sc.newInvocation( request );
310 servlet = (RepositoryServlet) ic.getServlet();
311 servlet.setDavSessionProvider( davSessionProvider );
313 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
314 archivaDavResourceFactory.setHttpAuth( httpAuth );
315 archivaDavResourceFactory.setServletAuth( servletAuth );
316 servlet.setResourceFactory( archivaDavResourceFactory );
318 AuthenticationResult result = new AuthenticationResult();
319 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
320 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
322 // ArchivaDavResourceFactory#isAuthorized()
323 SecuritySession session = new DefaultSecuritySession();
324 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
325 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
326 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
327 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
328 servletAuthControl.expectAndThrow(
329 servletAuth.isAuthorized( null, session, "internal",
330 ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
331 new UnauthorizedException( "User not authorized" ) );
333 httpAuthControl.replay();
334 servletAuthControl.replay();
336 servlet.service( ic.getRequest(), ic.getResponse() );
338 httpAuthControl.verify();
339 servletAuthControl.verify();
341 // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
344 // test deploy with a valid user with write access
346 public void testPutWithValidUserWithWriteAccess()
349 setupCleanRepo( repoRootInternal );
350 assertTrue( repoRootInternal.exists() );
352 String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
353 InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
354 assertNotNull( "artifact.jar inputstream", is );
356 WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
358 InvocationContext ic = sc.newInvocation( request );
359 servlet = (RepositoryServlet) ic.getServlet();
360 servlet.setDavSessionProvider( davSessionProvider );
362 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
363 archivaDavResourceFactory.setHttpAuth( httpAuth );
364 archivaDavResourceFactory.setServletAuth( servletAuth );
366 TestAuditListener listener = new TestAuditListener();
367 archivaDavResourceFactory.addAuditListener( listener );
368 servlet.setResourceFactory( archivaDavResourceFactory );
370 AuthenticationResult result = new AuthenticationResult();
371 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
372 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
374 User user = new SimpleUser();
375 user.setUsername( "admin" );
377 // ArchivaDavResourceFactory#isAuthorized()
378 SecuritySession session = new DefaultSecuritySession();
379 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
380 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
381 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), user );
382 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
383 servletAuthControl.expectAndReturn(
384 servletAuth.isAuthorized( null, session, "internal",
385 ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
388 httpAuthControl.replay();
389 servletAuthControl.replay();
391 servlet.service( ic.getRequest(), ic.getResponse() );
393 httpAuthControl.verify();
394 servletAuthControl.verify();
396 // assertEquals(HttpServletResponse.SC_CREATED, response.getResponseCode());
398 assertEquals( "admin", listener.getEvents().get( 0 ).getUserId() );
401 // test get with invalid user, and guest has read access to repo
403 public void testGetWithInvalidUserAndGuestHasReadAccess()
406 String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
407 String expectedArtifactContents = "dummy-commons-lang-artifact";
409 File artifactFile = new File( repoRootInternal, commonsLangJar );
410 artifactFile.getParentFile().mkdirs();
412 FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, Charset.defaultCharset() );
414 WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
415 InvocationContext ic = sc.newInvocation( request );
416 servlet = (RepositoryServlet) ic.getServlet();
417 servlet.setDavSessionProvider( davSessionProvider );
419 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
420 archivaDavResourceFactory.setHttpAuth( httpAuth );
421 archivaDavResourceFactory.setServletAuth( servletAuth );
423 servlet.setResourceFactory( archivaDavResourceFactory );
425 AuthenticationResult result = new AuthenticationResult();
426 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
427 servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
428 new AuthenticationException( "Authentication error" ) );
429 servletAuthControl.expectAndReturn(
430 servletAuth.isAuthorized( "guest", "internal",
431 ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS ),
434 // ArchivaDavResourceFactory#isAuthorized()
435 SecuritySession session = new DefaultSecuritySession();
436 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
437 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
438 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), null );
439 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
440 servletAuthControl.expectAndReturn(
441 servletAuth.isAuthorized( null, session, "internal",
442 ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
445 httpAuthControl.replay();
446 servletAuthControl.replay();
448 WebResponse response = sc.getResponse( request );
450 httpAuthControl.verify();
451 servletAuthControl.verify();
453 assertEquals( HttpServletResponse.SC_OK, response.getResponseCode() );
454 assertEquals( "Expected file contents", expectedArtifactContents, response.getText() );
457 // test get with invalid user, and guest has no read access to repo
459 public void testGetWithInvalidUserAndGuestHasNoReadAccess()
462 String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
463 String expectedArtifactContents = "dummy-commons-lang-artifact";
465 File artifactFile = new File( repoRootInternal, commonsLangJar );
466 artifactFile.getParentFile().mkdirs();
468 FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, Charset.defaultCharset() );
470 WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
471 InvocationContext ic = sc.newInvocation( request );
472 servlet = (RepositoryServlet) ic.getServlet();
473 servlet.setDavSessionProvider( davSessionProvider );
475 AuthenticationResult result = new AuthenticationResult();
476 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
477 servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
478 new AuthenticationException( "Authentication error" ) );
479 servletAuthControl.expectAndReturn(
480 servletAuth.isAuthorized( "guest", "internal",
481 ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS ),
484 httpAuthControl.replay();
485 servletAuthControl.replay();
487 WebResponse response = sc.getResponse( request );
489 httpAuthControl.verify();
490 servletAuthControl.verify();
492 assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );
495 // test get with valid user with read access to repo
497 public void testGetWithAValidUserWithReadAccess()
500 String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
501 String expectedArtifactContents = "dummy-commons-lang-artifact";
503 File artifactFile = new File( repoRootInternal, commonsLangJar );
504 artifactFile.getParentFile().mkdirs();
506 FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, Charset.defaultCharset() );
508 WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
509 InvocationContext ic = sc.newInvocation( request );
510 servlet = (RepositoryServlet) ic.getServlet();
511 servlet.setDavSessionProvider( davSessionProvider );
513 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
514 archivaDavResourceFactory.setHttpAuth( httpAuth );
515 archivaDavResourceFactory.setServletAuth( servletAuth );
517 servlet.setResourceFactory( archivaDavResourceFactory );
519 AuthenticationResult result = new AuthenticationResult();
520 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
521 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
523 // ArchivaDavResourceFactory#isAuthorized()
524 SecuritySession session = new DefaultSecuritySession();
525 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
526 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
527 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
528 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
529 servletAuthControl.expectAndReturn(
530 servletAuth.isAuthorized( null, session, "internal",
531 ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
534 httpAuthControl.replay();
535 servletAuthControl.replay();
537 WebResponse response = sc.getResponse( request );
539 httpAuthControl.verify();
540 servletAuthControl.verify();
542 assertEquals( HttpServletResponse.SC_OK, response.getResponseCode() );
543 assertEquals( "Expected file contents", expectedArtifactContents, response.getText() );
546 // test get with valid user with no read access to repo
548 public void testGetWithAValidUserWithNoReadAccess()
551 String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
552 String expectedArtifactContents = "dummy-commons-lang-artifact";
554 File artifactFile = new File( repoRootInternal, commonsLangJar );
555 artifactFile.getParentFile().mkdirs();
557 FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, Charset.defaultCharset() );
559 WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
560 InvocationContext ic = sc.newInvocation( request );
561 servlet = (RepositoryServlet) ic.getServlet();
562 servlet.setDavSessionProvider( davSessionProvider );
564 ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
565 archivaDavResourceFactory.setHttpAuth( httpAuth );
566 archivaDavResourceFactory.setServletAuth( servletAuth );
568 servlet.setResourceFactory( archivaDavResourceFactory );
570 AuthenticationResult result = new AuthenticationResult();
571 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
572 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
574 // ArchivaDavResourceFactory#isAuthorized()
575 SecuritySession session = new DefaultSecuritySession();
576 httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
577 httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
578 httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
579 servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
580 servletAuthControl.expectAndThrow(
581 servletAuth.isAuthorized( null, session, "internal",
582 ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
583 new UnauthorizedException( "User not authorized to read repository." ) );
585 httpAuthControl.replay();
586 servletAuthControl.replay();
588 WebResponse response = sc.getResponse( request );
590 httpAuthControl.verify();
591 servletAuthControl.verify();
593 assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );