1 package org.apache.maven.archiva.webdav;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import org.apache.commons.io.FileUtils;
28 import org.apache.jackrabbit.webdav.DavException;
29 import org.apache.jackrabbit.webdav.DavResourceLocator;
30 import org.apache.jackrabbit.webdav.DavServletRequest;
31 import org.apache.jackrabbit.webdav.DavServletResponse;
32 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
33 import org.apache.maven.archiva.configuration.Configuration;
34 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
35 import org.apache.maven.archiva.configuration.RepositoryGroupConfiguration;
36 import org.apache.maven.archiva.database.ArchivaAuditLogsDao;
37 import org.apache.maven.archiva.model.ArchivaAuditLogs;
38 import org.apache.maven.archiva.proxy.DefaultRepositoryProxyConnectors;
39 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
40 import org.apache.maven.archiva.repository.RepositoryContentFactory;
41 import org.apache.maven.archiva.repository.content.ManagedDefaultRepositoryContent;
42 import org.apache.maven.archiva.repository.content.RepositoryRequest;
43 import org.codehaus.plexus.spring.PlexusInSpringTestCase;
44 import org.easymock.MockControl;
45 import org.easymock.classextension.MockClassControl;
46
47
48
49
50 public class ArchivaDavResourceFactoryTest
51 extends PlexusInSpringTestCase
52 {
53 private static final String RELEASES_REPO = "releases";
54
55 private static final String INTERNAL_REPO = "internal";
56
57 private static final String LOCAL_MIRROR_REPO = "local-mirror";
58
59 private static final String LEGACY_REPO = "legacy-repo";
60
61 private static final String LOCAL_REPO_GROUP = "local";
62
63 private OverridingArchivaDavResourceFactory resourceFactory;
64
65 private MockControl requestControl;
66
67 private DavServletRequest request;
68
69 private MockControl repoRequestControl;
70
71 private RepositoryRequest repoRequest;
72
73 private MockControl responseControl;
74
75 private DavServletResponse response;
76
77 private MockControl archivaConfigurationControl;
78
79 private ArchivaConfiguration archivaConfiguration;
80
81 private Configuration config;
82
83 private MockControl repoContentFactoryControl;
84
85 private RepositoryContentFactory repoFactory;
86
87 private ArchivaAuditLogsDao auditLogsDao;
88
89 private MockControl auditLogsDaoControl;
90
91 public void setUp()
92 throws Exception
93 {
94 super.setUp();
95
96 requestControl = MockControl.createControl( DavServletRequest.class );
97 request = (DavServletRequest) requestControl.getMock();
98
99 responseControl = MockControl.createControl( DavServletResponse.class );
100 response = (DavServletResponse) responseControl.getMock();
101 responseControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
102
103 archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
104 archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
105
106 auditLogsDaoControl = MockControl.createControl( ArchivaAuditLogsDao.class );
107 auditLogsDaoControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
108 auditLogsDao = (ArchivaAuditLogsDao) auditLogsDaoControl.getMock();
109
110 config = new Configuration();
111 config.addManagedRepository( createManagedRepository( RELEASES_REPO, new File( getBasedir(),
112 "target/test-classes/" +
113 RELEASES_REPO ).getPath(),
114 "default" ) );
115 config.addManagedRepository( createManagedRepository( INTERNAL_REPO, new File( getBasedir(),
116 "target/test-classes/" +
117 INTERNAL_REPO ).getPath(),
118 "default" ) );
119
120 RepositoryGroupConfiguration repoGroupConfig = new RepositoryGroupConfiguration();
121 repoGroupConfig.setId( LOCAL_REPO_GROUP );
122 repoGroupConfig.addRepository( RELEASES_REPO );
123 repoGroupConfig.addRepository( INTERNAL_REPO );
124
125 config.addRepositoryGroup( repoGroupConfig );
126
127 repoContentFactoryControl = MockClassControl.createControl( RepositoryContentFactory.class );
128 repoFactory = (RepositoryContentFactory) repoContentFactoryControl.getMock();
129
130 repoRequestControl = MockClassControl.createControl( RepositoryRequest.class );
131 repoRequest = (RepositoryRequest) repoRequestControl.getMock();
132
133 resourceFactory = new OverridingArchivaDavResourceFactory();
134 resourceFactory.setArchivaConfiguration( archivaConfiguration );
135 resourceFactory.setRepositoryFactory( repoFactory );
136 resourceFactory.setRepositoryRequest( repoRequest );
137 resourceFactory.setConnectors( new OverridingRepositoryProxyConnectors() );
138 resourceFactory.setAuditLogsDao( auditLogsDao );
139 }
140
141 private ManagedRepositoryConfiguration createManagedRepository( String id, String location, String layout )
142 {
143 ManagedRepositoryConfiguration repoConfig = new ManagedRepositoryConfiguration();
144 repoConfig.setId( id );
145 repoConfig.setName( id );
146 repoConfig.setLocation( location );
147 repoConfig.setLayout( layout );
148
149 return repoConfig;
150 }
151
152 private ManagedRepositoryContent createManagedRepositoryContent( String repoId )
153 {
154 ManagedRepositoryContent repoContent = new ManagedDefaultRepositoryContent();
155 repoContent.setRepository( config.findManagedRepositoryById( repoId ) );
156
157 return repoContent;
158 }
159
160 public void tearDown()
161 throws Exception
162 {
163 super.tearDown();
164 }
165
166
167 public void testRepositoryGroupFirstRepositoryRequiresAuthentication()
168 throws Exception
169 {
170 DavResourceLocator locator =
171 new ArchivaDavResourceLocator( "", "/repository/" + LOCAL_REPO_GROUP +
172 "/org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar", LOCAL_REPO_GROUP,
173 new ArchivaDavLocatorFactory() );
174
175 ManagedRepositoryContent internalRepo = createManagedRepositoryContent( INTERNAL_REPO );
176
177 try
178 {
179 archivaConfigurationControl.expectAndReturn( archivaConfiguration.getConfiguration(), config );
180 requestControl.expectAndReturn( request.getMethod(), "GET", 2 );
181 repoContentFactoryControl.expectAndReturn( repoFactory.getManagedRepositoryContent( RELEASES_REPO ),
182 createManagedRepositoryContent( RELEASES_REPO ) );
183 requestControl.expectAndReturn( request.getRemoteAddr(), "http://localhost:8080", 2 );
184 requestControl.expectAndReturn( request.getDavSession(), new ArchivaDavSession(), 2 );
185 repoRequestControl.expectAndReturn(
186 repoRequest.isSupportFile( "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ),
187 false );
188 repoRequestControl.expectAndReturn(
189 repoRequest.isDefault( "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ),
190 false );
191 repoRequestControl.expectAndReturn(
192 repoRequest.toArtifactReference( "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ),
193 null );
194 repoRequestControl.expectAndReturn(
195 repoRequest.toNativePath(
196 "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar",
197 internalRepo ),
198 new File(
199 config.findManagedRepositoryById( INTERNAL_REPO ).getLocation(),
200 "target/test-classes/internal/org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ).getPath() );
201 repoContentFactoryControl.expectAndReturn( repoFactory.getManagedRepositoryContent( INTERNAL_REPO ),
202 internalRepo );
203
204 archivaConfigurationControl.replay();
205 requestControl.replay();
206 repoContentFactoryControl.replay();
207 repoRequestControl.replay();
208
209 resourceFactory.createResource( locator, request, response );
210
211 archivaConfigurationControl.verify();
212 requestControl.verify();
213 repoContentFactoryControl.verify();
214 repoRequestControl.verify();
215
216 fail( "A DavException with 401 error code should have been thrown." );
217 }
218 catch ( DavException e )
219 {
220 assertEquals( 401, e.getErrorCode() );
221 }
222 }
223
224 public void testRepositoryGroupLastRepositoryRequiresAuthentication()
225 throws Exception
226 {
227 DavResourceLocator locator =
228 new ArchivaDavResourceLocator( "", "/repository/" + LOCAL_REPO_GROUP +
229 "/org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar", LOCAL_REPO_GROUP,
230 new ArchivaDavLocatorFactory() );
231
232 List<RepositoryGroupConfiguration> repoGroups = new ArrayList<RepositoryGroupConfiguration>();
233 RepositoryGroupConfiguration repoGroup = new RepositoryGroupConfiguration();
234 repoGroup.setId( LOCAL_REPO_GROUP );
235 repoGroup.addRepository( INTERNAL_REPO );
236 repoGroup.addRepository( RELEASES_REPO );
237
238 repoGroups.add( repoGroup );
239
240 config.setRepositoryGroups( repoGroups );
241
242 ManagedRepositoryContent internalRepo = createManagedRepositoryContent( INTERNAL_REPO );
243
244 try
245 {
246 archivaConfigurationControl.expectAndReturn( archivaConfiguration.getConfiguration(), config );
247 requestControl.expectAndReturn( request.getMethod(), "GET", 2 );
248 repoContentFactoryControl.expectAndReturn( repoFactory.getManagedRepositoryContent( INTERNAL_REPO ),
249 internalRepo );
250 repoContentFactoryControl.expectAndReturn( repoFactory.getManagedRepositoryContent( RELEASES_REPO ),
251 createManagedRepositoryContent( RELEASES_REPO ) );
252 requestControl.expectAndReturn( request.getRemoteAddr(), "http://localhost:8080", 2 );
253 requestControl.expectAndReturn( request.getDavSession(), new ArchivaDavSession(), 2 );
254 repoRequestControl.expectAndReturn(
255 repoRequest.isSupportFile( "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ),
256 false );
257 repoRequestControl.expectAndReturn(
258 repoRequest.isDefault( "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ),
259 false );
260 repoRequestControl.expectAndReturn(
261 repoRequest.toArtifactReference( "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ),
262 null );
263 repoRequestControl.expectAndReturn(
264 repoRequest.toNativePath(
265 "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar",
266 internalRepo ),
267 new File(
268 config.findManagedRepositoryById( INTERNAL_REPO ).getLocation(),
269 "target/test-classes/internal/org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ).getPath() );
270
271 archivaConfigurationControl.replay();
272 requestControl.replay();
273 repoContentFactoryControl.replay();
274 repoRequestControl.replay();
275
276 resourceFactory.createResource( locator, request, response );
277
278 archivaConfigurationControl.verify();
279 requestControl.verify();
280 repoContentFactoryControl.verify();
281 repoRequestControl.verify();
282
283 fail( "A DavException with 401 error code should have been thrown." );
284 }
285 catch ( DavException e )
286 {
287 assertEquals( 401, e.getErrorCode() );
288 }
289 }
290
291 public void testRepositoryGroupArtifactDoesNotExistInAnyOfTheReposAuthenticationDisabled()
292 throws Exception
293 {
294 DavResourceLocator locator =
295 new ArchivaDavResourceLocator( "", "/repository/" + LOCAL_REPO_GROUP +
296 "/org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar", LOCAL_REPO_GROUP,
297 new ArchivaDavLocatorFactory() );
298
299 config.addManagedRepository( createManagedRepository( LOCAL_MIRROR_REPO,
300 new File( getBasedir(),
301 "target/test-classes/local-mirror" ).getPath(),
302 "default" ) );
303
304 List<RepositoryGroupConfiguration> repoGroups = new ArrayList<RepositoryGroupConfiguration>();
305 RepositoryGroupConfiguration repoGroup = new RepositoryGroupConfiguration();
306 repoGroup.setId( LOCAL_REPO_GROUP );
307 repoGroup.addRepository( INTERNAL_REPO );
308 repoGroup.addRepository( LOCAL_MIRROR_REPO );
309
310 repoGroups.add( repoGroup );
311
312 config.setRepositoryGroups( repoGroups );
313
314 ManagedRepositoryContent internalRepo = createManagedRepositoryContent( INTERNAL_REPO );
315 ManagedRepositoryContent localMirrorRepo = createManagedRepositoryContent( LOCAL_MIRROR_REPO );
316
317 try
318 {
319 archivaConfigurationControl.expectAndReturn( archivaConfiguration.getConfiguration(), config );
320 requestControl.expectAndReturn( request.getMethod(), "GET", 4 );
321 repoContentFactoryControl.expectAndReturn( repoFactory.getManagedRepositoryContent( INTERNAL_REPO ),
322 internalRepo );
323 repoContentFactoryControl.expectAndReturn( repoFactory.getManagedRepositoryContent( LOCAL_MIRROR_REPO ),
324 localMirrorRepo );
325 requestControl.expectAndReturn( request.getRemoteAddr(), "http://localhost:8080", 4 );
326 requestControl.expectAndReturn( request.getDavSession(), new ArchivaDavSession(), 4 );
327 repoRequestControl.expectAndReturn(
328 repoRequest.isSupportFile( "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ),
329 false, 2 );
330 repoRequestControl.expectAndReturn(
331 repoRequest.isDefault( "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ),
332 false, 2 );
333 repoRequestControl.expectAndReturn(
334 repoRequest.toArtifactReference( "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ),
335 null, 2 );
336 repoRequestControl.expectAndReturn(
337 repoRequest.toNativePath(
338 "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar",
339 internalRepo ),
340 new File(
341 config.findManagedRepositoryById( INTERNAL_REPO ).getLocation(),
342 "target/test-classes/internal/org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ).getPath() );
343
344 repoRequestControl.expectAndReturn(
345 repoRequest.toNativePath(
346 "org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar",
347 localMirrorRepo ),
348 new File(
349 config.findManagedRepositoryById( LOCAL_MIRROR_REPO ).getLocation(),
350 "target/test-classes/internal/org/apache/archiva/archiva/1.2-SNAPSHOT/archiva-1.2-SNAPSHOT.jar" ).getPath() );
351
352 archivaConfigurationControl.replay();
353 requestControl.replay();
354 repoContentFactoryControl.replay();
355 repoRequestControl.replay();
356
357 resourceFactory.createResource( locator, request, response );
358
359 archivaConfigurationControl.verify();
360 requestControl.verify();
361 repoContentFactoryControl.verify();
362 repoRequestControl.verify();
363
364 fail( "A DavException with 404 error code should have been thrown." );
365 }
366 catch ( DavException e )
367 {
368 assertEquals( 404, e.getErrorCode() );
369 }
370 }
371
372
373 public void testRequestArtifactMetadataThreePartsRepoHasDefaultLayout()
374 throws Exception
375 {
376
377 DavResourceLocator locator =
378 new ArchivaDavResourceLocator( "", "/repository/" + INTERNAL_REPO + "/eclipse/jdtcore/maven-metadata.xml", INTERNAL_REPO,
379 new ArchivaDavLocatorFactory() );
380
381 ManagedRepositoryContent internalRepo = createManagedRepositoryContent( INTERNAL_REPO );
382
383
384 RepositoryRequest repoRequest = (RepositoryRequest) lookup( RepositoryRequest.class );
385 resourceFactory.setRepositoryRequest( repoRequest );
386
387 try
388 {
389 archivaConfigurationControl.expectAndReturn( archivaConfiguration.getConfiguration(), config );
390 repoContentFactoryControl.expectAndReturn( repoFactory.getManagedRepositoryContent( INTERNAL_REPO ),
391 internalRepo );
392 requestControl.expectAndReturn( request.getMethod(), "GET", 3 );
393 requestControl.expectAndReturn( request.getRemoteAddr(), "http://localhost:8080", 3 );
394 requestControl.expectAndReturn( request.getDavSession(), new ArchivaDavSession(), 2 );
395 requestControl.expectAndReturn( request.getRequestURI(), "http://localhost:8080/archiva/repository/" +
396 INTERNAL_REPO + "/eclipse/jdtcore/maven-metadata.xml" );
397 response.addHeader( "Pragma", "no-cache" );
398 responseControl.setVoidCallable();
399
400 response.addHeader( "Cache-Control", "no-cache" );
401 responseControl.setVoidCallable();
402
403 long date = 2039842134;
404 response.addDateHeader( "last-modified", date );
405 responseControl.setVoidCallable();
406
407 archivaConfigurationControl.replay();
408 repoContentFactoryControl.replay();
409 requestControl.replay();
410 responseControl.replay();
411
412 resourceFactory.createResource( locator, request, response );
413
414 archivaConfigurationControl.verify();
415 repoContentFactoryControl.verify();
416 requestControl.verify();
417 responseControl.verify();
418 }
419 catch ( DavException e )
420 {
421 fail( "A DavException should not have been thrown!" );
422 }
423 }
424
425 public void testRequestArtifactMetadataTwoPartsRepoHasDefaultLayout()
426 throws Exception
427 {
428
429 DavResourceLocator locator =
430 new ArchivaDavResourceLocator( "", "/repository/" + INTERNAL_REPO + "/eclipse/maven-metadata.xml", INTERNAL_REPO,
431 new ArchivaDavLocatorFactory() );
432
433 ManagedRepositoryContent internalRepo = createManagedRepositoryContent( INTERNAL_REPO );
434
435
436 RepositoryRequest repoRequest = (RepositoryRequest) lookup( RepositoryRequest.class );
437 resourceFactory.setRepositoryRequest( repoRequest );
438
439 try
440 {
441 archivaConfigurationControl.expectAndReturn( archivaConfiguration.getConfiguration(), config );
442 repoContentFactoryControl.expectAndReturn( repoFactory.getManagedRepositoryContent( INTERNAL_REPO ),
443 internalRepo );
444 requestControl.expectAndReturn( request.getMethod(), "GET", 2 );
445 requestControl.expectAndReturn( request.getRemoteAddr(), "http://localhost:8080", 2 );
446 requestControl.expectAndReturn( request.getDavSession(), new ArchivaDavSession(), 2 );
447
448 archivaConfigurationControl.replay();
449 repoContentFactoryControl.replay();
450 requestControl.replay();
451
452 resourceFactory.createResource( locator, request, response );
453
454 archivaConfigurationControl.verify();
455 repoContentFactoryControl.verify();
456 requestControl.verify();
457
458 fail( "A 404 error should have been thrown!" );
459 }
460 catch ( DavException e )
461 {
462 assertEquals( 404, e.getErrorCode() );
463 }
464 }
465
466 public void testRequestMetadataRepoIsLegacy()
467 throws Exception
468 {
469 config.addManagedRepository( createManagedRepository( LEGACY_REPO, new File( getBasedir(),
470 "target/test-classes/" +
471 LEGACY_REPO ).getPath(),
472 "legacy" ) );
473 DavResourceLocator locator =
474 new ArchivaDavResourceLocator( "", "/repository/" + LEGACY_REPO + "/eclipse/maven-metadata.xml", LEGACY_REPO,
475 new ArchivaDavLocatorFactory() );
476
477 ManagedRepositoryContent legacyRepo = createManagedRepositoryContent( LEGACY_REPO );
478
479
480 RepositoryRequest repoRequest = (RepositoryRequest) lookup( RepositoryRequest.class );
481 resourceFactory.setRepositoryRequest( repoRequest );
482
483 try
484 {
485 archivaConfigurationControl.expectAndReturn( archivaConfiguration.getConfiguration(), config );
486 repoContentFactoryControl.expectAndReturn( repoFactory.getManagedRepositoryContent( LEGACY_REPO ),
487 legacyRepo );
488 requestControl.expectAndReturn( request.getMethod(), "GET", 2 );
489 requestControl.expectAndReturn( request.getRemoteAddr(), "http://localhost:8080", 2 );
490 requestControl.expectAndReturn( request.getDavSession(), new ArchivaDavSession(), 2 );
491
492 archivaConfigurationControl.replay();
493 repoContentFactoryControl.replay();
494 requestControl.replay();
495
496 resourceFactory.createResource( locator, request, response );
497
498 archivaConfigurationControl.verify();
499 repoContentFactoryControl.verify();
500 requestControl.verify();
501
502 fail( "A 404 error should have been thrown!" );
503 }
504 catch ( DavException e )
505 {
506 assertEquals( 404, e.getErrorCode() );
507 }
508 }
509
510 class OverridingArchivaDavResourceFactory
511 extends ArchivaDavResourceFactory
512 {
513 protected boolean isAuthorized( DavServletRequest request, String repositoryId )
514 throws DavException
515 {
516 if ( RELEASES_REPO.equals( repositoryId ) )
517 {
518 throw new UnauthorizedDavException( repositoryId,
519 "You are not authenticated and authorized to access any repository." );
520 }
521 else
522 {
523 return true;
524 }
525 }
526
527 protected String getActivePrincipal( DavServletRequest request )
528 {
529 return "guest";
530 }
531 }
532
533 class OverridingRepositoryProxyConnectors
534 extends DefaultRepositoryProxyConnectors
535 {
536 public File fetchMetatadaFromProxies( ManagedRepositoryContent repository, String logicalPath )
537 {
538 File target = new File( repository.getRepoRoot(), logicalPath );
539 try
540 {
541 FileUtils.copyFile( new File( getBasedir(), "target/test-classes/maven-metadata.xml" ), target );
542 }
543 catch ( IOException e )
544 {
545
546 }
547
548 return target;
549 }
550 }
551 }