]> source.dussan.org Git - archiva.git/blob
f1301aabcf28b932366d3c72d2d2500388f1b737
[archiva.git] /
1 package org.apache.maven.archiva.webdav;
2
3 /*
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
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  * under the License.
20  */
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.InputStream;
25
26 import javax.servlet.http.HttpServletResponse;
27
28 import net.sf.ehcache.CacheManager;
29
30 import org.apache.commons.io.FileUtils;
31 import org.apache.jackrabbit.webdav.DavResourceFactory;
32 import org.apache.jackrabbit.webdav.DavSessionProvider;
33 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
34 import org.apache.maven.archiva.configuration.Configuration;
35 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
36 import org.apache.maven.archiva.security.ArchivaXworkUser;
37 import org.apache.maven.archiva.security.ServletAuthenticator;
38 import org.codehaus.plexus.redback.authentication.AuthenticationException;
39 import org.codehaus.plexus.redback.authentication.AuthenticationResult;
40 import org.codehaus.plexus.redback.authorization.UnauthorizedException;
41 import org.codehaus.plexus.redback.system.DefaultSecuritySession;
42 import org.codehaus.plexus.redback.system.SecuritySession;
43 import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator;
44 import org.codehaus.plexus.redback.xwork.filter.authentication.basic.HttpBasicAuthentication;
45 import org.codehaus.plexus.spring.PlexusInSpringTestCase;
46 import org.easymock.MockControl;
47 import org.easymock.classextension.MockClassControl;
48 import org.easymock.internal.AlwaysMatcher;
49
50 import com.meterware.httpunit.GetMethodWebRequest;
51 import com.meterware.httpunit.HttpUnitOptions;
52 import com.meterware.httpunit.PutMethodWebRequest;
53 import com.meterware.httpunit.WebRequest;
54 import com.meterware.httpunit.WebResponse;
55 import com.meterware.servletunit.InvocationContext;
56 import com.meterware.servletunit.ServletRunner;
57 import com.meterware.servletunit.ServletUnitClient;
58
59 /**
60  * RepositoryServletSecurityTest
61  * 
62  * Test the flow of the authentication and authorization checks. This does not necessarily
63  * perform redback security checking.
64  * 
65  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
66  * @version $Id$
67  */
68 public class RepositoryServletSecurityTest
69     extends PlexusInSpringTestCase
70 {
71     protected static final String REPOID_INTERNAL = "internal";
72
73     protected ServletUnitClient sc;
74
75     protected File repoRootInternal;
76
77     private ServletRunner sr;
78
79     protected ArchivaConfiguration archivaConfiguration;
80
81     private DavSessionProvider davSessionProvider;
82
83     private MockControl servletAuthControl;
84
85     private ServletAuthenticator servletAuth;
86
87     private MockClassControl httpAuthControl;
88
89     private HttpAuthenticator httpAuth;
90
91     private ArchivaXworkUser archivaXworkUser;
92
93     private RepositoryServlet servlet;
94
95     private MockControl davResourceFactoryControl;
96
97     private DavResourceFactory davResourceFactory;
98
99     public void setUp()
100         throws Exception
101     {
102         super.setUp();
103
104         String appserverBase = getTestFile( "target/appserver-base" ).getAbsolutePath();
105         System.setProperty( "appserver.base", appserverBase );
106
107         File testConf = getTestFile( "src/test/resources/repository-archiva.xml" );
108         File testConfDest = new File( appserverBase, "conf/archiva.xml" );
109         FileUtils.copyFile( testConf, testConfDest );
110
111         archivaConfiguration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class );
112         repoRootInternal = new File( appserverBase, "data/repositories/internal" );
113         Configuration config = archivaConfiguration.getConfiguration();
114
115         config.addManagedRepository( createManagedRepository( REPOID_INTERNAL, "Internal Test Repo", repoRootInternal ) );
116         saveConfiguration( archivaConfiguration );
117
118         CacheManager.getInstance().removeCache( "url-failures-cache" );
119
120         HttpUnitOptions.setExceptionsThrownOnErrorStatus( false );
121
122         sr = new ServletRunner( getTestFile( "src/test/resources/WEB-INF/repository-servlet-security-test/web.xml" ) );
123         sr.registerServlet( "/repository/*", RepositoryServlet.class.getName() );
124         sc = sr.newClient();
125
126         servletAuthControl = MockControl.createControl( ServletAuthenticator.class );
127         servletAuthControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
128         servletAuth = (ServletAuthenticator) servletAuthControl.getMock();
129
130         httpAuthControl =
131             MockClassControl.createControl( HttpBasicAuthentication.class, HttpBasicAuthentication.class.getMethods() );
132         httpAuthControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
133         httpAuth = (HttpAuthenticator) httpAuthControl.getMock();
134
135         archivaXworkUser = new ArchivaXworkUser();
136         archivaXworkUser.setGuest( "guest" );
137
138         davSessionProvider = new ArchivaDavSessionProvider( servletAuth, httpAuth, archivaXworkUser );
139
140         davResourceFactoryControl = MockControl.createControl( DavResourceFactory.class );
141         davResourceFactoryControl.setDefaultMatcher( new AlwaysMatcher() );
142         davResourceFactory = (DavResourceFactory) davResourceFactoryControl.getMock();
143     }
144
145     protected ManagedRepositoryConfiguration createManagedRepository( String id, String name, File location )
146     {
147         ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration();
148         repo.setId( id );
149         repo.setName( name );
150         repo.setLocation( location.getAbsolutePath() );
151         return repo;
152     }
153
154     protected void saveConfiguration()
155         throws Exception
156     {
157         saveConfiguration( archivaConfiguration );
158     }
159
160     protected void saveConfiguration( ArchivaConfiguration archivaConfiguration )
161         throws Exception
162     {
163         archivaConfiguration.save( archivaConfiguration.getConfiguration() );
164     }
165
166     protected void setupCleanRepo( File repoRootDir )
167         throws IOException
168     {
169         FileUtils.deleteDirectory( repoRootDir );
170         if ( !repoRootDir.exists() )
171         {
172             repoRootDir.mkdirs();
173         }
174     }
175
176     @Override
177     protected String getPlexusConfigLocation()
178     {
179         return "org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml";
180     }
181
182     @Override
183     protected void tearDown()
184         throws Exception
185     {
186         if ( sc != null )
187         {
188             sc.clearContents();
189         }
190
191         if ( sr != null )
192         {
193             sr.shutDown();
194         }
195
196         if ( repoRootInternal.exists() )
197         {
198             FileUtils.deleteDirectory(repoRootInternal);
199         }
200
201         servlet = null;
202         
203         super.tearDown();
204     }
205
206     // test deploy with invalid user, and guest has no write access to repo
207     // 401 must be returned
208     public void testPutWithInvalidUserAndGuestHasNoWriteAccess()
209         throws Exception
210     {
211         setupCleanRepo( repoRootInternal );
212
213         String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
214         InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
215         assertNotNull( "artifact.jar inputstream", is );
216
217         WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
218         InvocationContext ic = sc.newInvocation( request );
219         servlet = (RepositoryServlet) ic.getServlet();
220         servlet.setDavSessionProvider( davSessionProvider );
221
222         AuthenticationResult result = new AuthenticationResult();
223         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
224         servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
225                            new AuthenticationException( "Authentication error" ) );
226         
227         servletAuth.isAuthorized( "guest", "internal", true );        
228         servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
229         servletAuthControl.setThrowable( new UnauthorizedException( "'guest' has no write access to repository" ) );
230
231         httpAuthControl.replay();
232         servletAuthControl.replay();
233
234         //WebResponse response = sc.getResponse( request );
235         servlet.service( ic.getRequest(), ic.getResponse() );
236         
237         httpAuthControl.verify();
238         servletAuthControl.verify();
239
240         //assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
241     }
242
243     // test deploy with invalid user, but guest has write access to repo
244     public void testPutWithInvalidUserAndGuestHasWriteAccess()
245         throws Exception
246     {
247         setupCleanRepo( repoRootInternal );
248
249         String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
250         InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
251         assertNotNull( "artifact.jar inputstream", is );
252
253         WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
254
255         InvocationContext ic = sc.newInvocation( request );
256         servlet = (RepositoryServlet) ic.getServlet();
257         servlet.setDavSessionProvider( davSessionProvider );
258
259         ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
260         archivaDavResourceFactory.setHttpAuth( httpAuth );
261         archivaDavResourceFactory.setServletAuth( servletAuth );
262
263         servlet.setResourceFactory( archivaDavResourceFactory );
264         
265         AuthenticationResult result = new AuthenticationResult();
266         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
267         servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
268                                            new AuthenticationException( "Authentication error" ) );
269         
270         servletAuth.isAuthorized( "guest", "internal", true );
271         servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
272         servletAuthControl.setReturnValue( true );
273         //servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", true ), true );
274         
275      // ArchivaDavResourceFactory#isAuthorized()
276         SecuritySession session = new DefaultSecuritySession();
277         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
278         httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
279         servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, result ),
280                                            new AuthenticationException( "Authentication error" ) );
281         
282         // check if guest has write access
283         servletAuth.isAuthorized( "guest", "internal", true );
284         servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
285         servletAuthControl.setReturnValue( true );
286         //servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", true ), true );
287         
288         httpAuthControl.replay();
289         servletAuthControl.replay();
290
291         //WebResponse response = sc.getResponse( request );
292         servlet.service( ic.getRequest(), ic.getResponse() );
293
294         httpAuthControl.verify();
295         servletAuthControl.verify();
296
297         // assertEquals( HttpServletResponse.SC_CREATED, response.getResponseCode() );
298     }
299
300     // test deploy with a valid user with no write access
301     public void testPutWithValidUserWithNoWriteAccess()
302         throws Exception
303     {
304         setupCleanRepo( repoRootInternal );
305
306         String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
307         InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
308         assertNotNull( "artifact.jar inputstream", is );
309         
310         WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
311         
312         InvocationContext ic = sc.newInvocation( request ); 
313         servlet = (RepositoryServlet) ic.getServlet();
314         servlet.setDavSessionProvider( davSessionProvider );
315         
316         ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
317         archivaDavResourceFactory.setHttpAuth( httpAuth );
318         archivaDavResourceFactory.setServletAuth( servletAuth );
319         servlet.setResourceFactory( archivaDavResourceFactory );
320
321         AuthenticationResult result = new AuthenticationResult();
322         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
323         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
324         
325      // ArchivaDavResourceFactory#isAuthorized()
326         SecuritySession session = new DefaultSecuritySession();
327         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
328         httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
329         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
330         servletAuthControl.expectAndThrow( servletAuth.isAuthorized( null, session, "internal", true ),
331                                            new UnauthorizedException( "User not authorized" ) );
332                 
333         httpAuthControl.replay();
334         servletAuthControl.replay();
335         
336         //WebResponse response = sc.getResponse( request );
337         servlet.service( ic.getRequest(), ic.getResponse() );
338
339         httpAuthControl.verify();
340         servletAuthControl.verify();
341         
342         // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
343     }
344
345     // test deploy with a valid user with write access
346     public void testPutWithValidUserWithWriteAccess()
347         throws Exception
348     {
349         setupCleanRepo( repoRootInternal );
350         assertTrue( repoRootInternal.exists() );
351
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 );
355
356         WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
357
358         InvocationContext ic = sc.newInvocation( request );
359         servlet = (RepositoryServlet) ic.getServlet();
360         servlet.setDavSessionProvider( davSessionProvider );
361
362         ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
363         archivaDavResourceFactory.setHttpAuth( httpAuth );
364         archivaDavResourceFactory.setServletAuth( servletAuth );
365
366         servlet.setResourceFactory( archivaDavResourceFactory );
367
368         AuthenticationResult result = new AuthenticationResult();
369         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
370         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
371
372         // ArchivaDavResourceFactory#isAuthorized()
373         SecuritySession session = new DefaultSecuritySession();
374         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
375         httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
376         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
377         servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true );
378
379         httpAuthControl.replay();
380         servletAuthControl.replay();
381
382         // WebResponse response = sc.getResponse( request );
383         // WebResponse response = ic.getServletResponse();
384
385         servlet.service( ic.getRequest(), ic.getResponse() );
386
387         httpAuthControl.verify();
388         servletAuthControl.verify();
389
390         // assertEquals(HttpServletResponse.SC_CREATED, response.getResponseCode());
391     }
392
393     // test get with invalid user, and guest has read access to repo
394     public void testGetWithInvalidUserAndGuestHasReadAccess()
395         throws Exception
396     {
397         String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
398         String expectedArtifactContents = "dummy-commons-lang-artifact";
399
400         File artifactFile = new File( repoRootInternal, commonsLangJar );
401         artifactFile.getParentFile().mkdirs();
402
403         FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
404
405         WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
406         InvocationContext ic = sc.newInvocation( request );
407         servlet = (RepositoryServlet) ic.getServlet();
408         servlet.setDavSessionProvider( davSessionProvider );
409         
410         ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
411         archivaDavResourceFactory.setHttpAuth( httpAuth );
412         archivaDavResourceFactory.setServletAuth( servletAuth );
413
414         servlet.setResourceFactory( archivaDavResourceFactory );
415
416         AuthenticationResult result = new AuthenticationResult();
417         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
418         servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
419                                            new AuthenticationException( "Authentication error" ) );
420         servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", false ), true );
421         
422      // ArchivaDavResourceFactory#isAuthorized()
423         SecuritySession session = new DefaultSecuritySession();
424         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
425         httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
426         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
427         servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true );
428
429         httpAuthControl.replay();
430         servletAuthControl.replay();
431
432         WebResponse response = sc.getResponse( request );
433
434         httpAuthControl.verify();
435         servletAuthControl.verify();
436
437         assertEquals( HttpServletResponse.SC_OK, response.getResponseCode() );
438         assertEquals( "Expected file contents", expectedArtifactContents, response.getText() );
439     }
440
441     // test get with invalid user, and guest has no read access to repo
442     public void testGetWithInvalidUserAndGuestHasNoReadAccess()
443         throws Exception
444     {
445         String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
446         String expectedArtifactContents = "dummy-commons-lang-artifact";
447
448         File artifactFile = new File( repoRootInternal, commonsLangJar );
449         artifactFile.getParentFile().mkdirs();
450
451         FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
452
453         WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
454         InvocationContext ic = sc.newInvocation( request );
455         servlet = (RepositoryServlet) ic.getServlet();
456         servlet.setDavSessionProvider( davSessionProvider );
457
458         AuthenticationResult result = new AuthenticationResult();
459         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
460         servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
461                                            new AuthenticationException( "Authentication error" ) );
462         servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", false ), false );
463
464         httpAuthControl.replay();
465         servletAuthControl.replay();
466
467         WebResponse response = sc.getResponse( request );
468
469         httpAuthControl.verify();
470         servletAuthControl.verify();
471
472         assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );
473     }
474
475     // test get with valid user with read access to repo
476     public void testGetWithAValidUserWithReadAccess()
477         throws Exception
478     {
479         String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
480         String expectedArtifactContents = "dummy-commons-lang-artifact";
481
482         File artifactFile = new File( repoRootInternal, commonsLangJar );
483         artifactFile.getParentFile().mkdirs();
484
485         FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
486
487         WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
488         InvocationContext ic = sc.newInvocation( request );
489         servlet = (RepositoryServlet) ic.getServlet();
490         servlet.setDavSessionProvider( davSessionProvider );
491
492         ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
493         archivaDavResourceFactory.setHttpAuth( httpAuth );
494         archivaDavResourceFactory.setServletAuth( servletAuth );
495
496         servlet.setResourceFactory( archivaDavResourceFactory );
497         
498         AuthenticationResult result = new AuthenticationResult();
499         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
500         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
501         
502      // ArchivaDavResourceFactory#isAuthorized()
503         SecuritySession session = new DefaultSecuritySession();
504         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
505         httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
506         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
507         servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true );
508         
509         httpAuthControl.replay();
510         servletAuthControl.replay();
511
512         WebResponse response = sc.getResponse( request );
513         
514         httpAuthControl.verify();
515         servletAuthControl.verify();
516
517         assertEquals( HttpServletResponse.SC_OK, response.getResponseCode() );
518         assertEquals( "Expected file contents", expectedArtifactContents, response.getText() );
519     }
520
521     // test get with valid user with no read access to repo
522     public void testGetWithAValidUserWithNoReadAccess()
523         throws Exception
524     {
525         String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
526         String expectedArtifactContents = "dummy-commons-lang-artifact";
527
528         File artifactFile = new File( repoRootInternal, commonsLangJar );
529         artifactFile.getParentFile().mkdirs();
530
531         FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
532
533         WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
534         InvocationContext ic = sc.newInvocation( request );
535         servlet = (RepositoryServlet) ic.getServlet();
536         servlet.setDavSessionProvider( davSessionProvider );
537         servlet.setResourceFactory( davResourceFactory );
538
539         AuthenticationResult result = new AuthenticationResult();
540         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
541         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
542
543         //TODO remove davResourceFactoryControl!
544         davResourceFactoryControl.expectAndThrow( davResourceFactory.createResource( null, null, null ),
545                                                   new UnauthorizedDavException( "internal", "User not authorized" ) );
546
547         httpAuthControl.replay();
548         servletAuthControl.replay();
549         davResourceFactoryControl.replay();
550
551         WebResponse response = sc.getResponse( request );
552
553         httpAuthControl.verify();
554         servletAuthControl.verify();
555         davResourceFactoryControl.verify();
556
557         assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );
558     }
559 }