This project has retired. For details please refer to its
Attic page.
ArchivaDavResourceFactory xref
1 package org.apache.archiva.webdav;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
23 import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin;
24 import org.apache.archiva.audit.Auditable;
25 import org.apache.archiva.checksum.ChecksumAlgorithm;
26 import org.apache.archiva.checksum.ChecksumUtil;
27 import org.apache.archiva.checksum.StreamingChecksum;
28 import org.apache.archiva.common.filelock.DefaultFileLockManager;
29 import org.apache.archiva.common.filelock.FileLockManager;
30 import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
31 import org.apache.archiva.common.utils.PathUtil;
32 import org.apache.archiva.common.utils.VersionUtil;
33 import org.apache.archiva.configuration.ArchivaConfiguration;
34 import org.apache.archiva.indexer.ArchivaIndexingContext;
35 import org.apache.archiva.indexer.merger.IndexMerger;
36 import org.apache.archiva.indexer.merger.IndexMergerException;
37 import org.apache.archiva.indexer.merger.IndexMergerRequest;
38 import org.apache.archiva.indexer.merger.base.MergedRemoteIndexesTask;
39 import org.apache.archiva.indexer.merger.base.MergedRemoteIndexesTaskRequest;
40 import org.apache.archiva.indexer.merger.TemporaryGroupIndex;
41 import org.apache.archiva.indexer.search.RepositorySearch;
42 import org.apache.archiva.indexer.search.RepositorySearchException;
43 import org.apache.archiva.maven2.metadata.MavenMetadataReader;
44 import org.apache.archiva.metadata.model.facets.AuditEvent;
45 import org.apache.archiva.metadata.repository.storage.RelocationException;
46 import org.apache.archiva.metadata.repository.storage.RepositoryStorage;
47 import org.apache.archiva.model.ArchivaRepositoryMetadata;
48 import org.apache.archiva.model.ArtifactReference;
49 import org.apache.archiva.policies.ProxyDownloadException;
50 import org.apache.archiva.proxy.ProxyRegistry;
51 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
52 import org.apache.archiva.redback.authentication.AuthenticationException;
53 import org.apache.archiva.redback.authentication.AuthenticationResult;
54 import org.apache.archiva.redback.authorization.AuthorizationException;
55 import org.apache.archiva.redback.authorization.UnauthorizedException;
56 import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator;
57 import org.apache.archiva.redback.policy.AccountLockedException;
58 import org.apache.archiva.redback.policy.MustChangePasswordException;
59 import org.apache.archiva.redback.system.SecuritySession;
60 import org.apache.archiva.redback.users.User;
61 import org.apache.archiva.redback.users.UserManager;
62 import org.apache.archiva.repository.LayoutException;
63 import org.apache.archiva.repository.ManagedRepository;
64 import org.apache.archiva.repository.ManagedRepositoryContent;
65 import org.apache.archiva.repository.ReleaseScheme;
66 import org.apache.archiva.repository.RepositoryGroup;
67 import org.apache.archiva.repository.RepositoryRegistry;
68 import org.apache.archiva.repository.RepositoryRequestInfo;
69 import org.apache.archiva.repository.storage.FilesystemStorage;
70 import org.apache.archiva.repository.storage.StorageAsset;
71 import org.apache.archiva.metadata.audit.AuditListener;
72 import org.apache.archiva.repository.features.IndexCreationFeature;
73 import org.apache.archiva.repository.metadata.base.MetadataTools;
74 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
75 import org.apache.archiva.repository.metadata.base.RepositoryMetadataMerge;
76 import org.apache.archiva.repository.metadata.base.RepositoryMetadataWriter;
77 import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler;
78 import org.apache.archiva.security.ServletAuthenticator;
79 import org.apache.archiva.webdav.util.MimeTypes;
80 import org.apache.archiva.webdav.util.TemporaryGroupIndexSessionCleaner;
81 import org.apache.archiva.webdav.util.WebdavMethodUtil;
82 import org.apache.archiva.xml.XMLException;
83 import org.apache.commons.io.FilenameUtils;
84 import org.apache.commons.lang3.StringUtils;
85 import org.apache.commons.lang3.SystemUtils;
86 import org.apache.jackrabbit.webdav.DavException;
87 import org.apache.jackrabbit.webdav.DavResource;
88 import org.apache.jackrabbit.webdav.DavResourceFactory;
89 import org.apache.jackrabbit.webdav.DavResourceLocator;
90 import org.apache.jackrabbit.webdav.DavServletRequest;
91 import org.apache.jackrabbit.webdav.DavServletResponse;
92 import org.apache.jackrabbit.webdav.DavSession;
93 import org.apache.jackrabbit.webdav.lock.LockManager;
94 import org.apache.jackrabbit.webdav.lock.SimpleLockManager;
95 import org.slf4j.Logger;
96 import org.slf4j.LoggerFactory;
97 import org.slf4j.MarkerFactory;
98 import org.springframework.context.ApplicationContext;
99 import org.springframework.stereotype.Service;
100
101 import javax.annotation.PostConstruct;
102 import javax.inject.Inject;
103 import javax.inject.Named;
104 import javax.servlet.http.HttpServletResponse;
105 import javax.servlet.http.HttpSession;
106 import java.io.IOException;
107 import java.io.OutputStream;
108 import java.io.OutputStreamWriter;
109 import java.nio.file.Files;
110 import java.nio.file.Path;
111 import java.nio.file.Paths;
112 import java.util.ArrayList;
113 import java.util.Date;
114 import java.util.HashMap;
115 import java.util.HashSet;
116 import java.util.List;
117 import java.util.Map;
118 import java.util.Objects;
119 import java.util.Set;
120 import java.util.stream.Collectors;
121
122
123
124
125 @Service( "davResourceFactory#archiva" )
126 public class ArchivaDavResourceFactory
127 implements DavResourceFactory, Auditable
128 {
129 private static final String PROXIED_SUFFIX = " (proxied)";
130
131 private static final String HTTP_PUT_METHOD = "PUT";
132
133 private Logger log = LoggerFactory.getLogger( ArchivaDavResourceFactory.class );
134
135 @Inject
136 private List<AuditListener> auditListeners = new ArrayList<>();
137
138 @Inject
139 private ProxyRegistry proxyRegistry;
140
141 @Inject
142 private MetadataTools metadataTools;
143
144 @Inject
145 private MimeTypes mimeTypes;
146
147 private ArchivaConfiguration archivaConfiguration;
148
149 @Inject
150 private ServletAuthenticator servletAuth;
151
152 @Inject
153 @Named( value = "httpAuthenticator#basic" )
154 private HttpAuthenticator httpAuth;
155
156 @Inject
157 private RemoteRepositoryAdmin remoteRepositoryAdmin;
158
159 @Inject
160 private ManagedRepositoryAdmin managedRepositoryAdmin;
161
162 @Inject
163 private RepositoryRegistry repositoryRegistry;
164
165 @Inject
166 private IndexMerger indexMerger;
167
168 @Inject
169 private RepositorySearch repositorySearch;
170
171
172
173
174 private final LockManager lockManager = new SimpleLockManager();
175
176 @Inject
177 @Named( value = "archivaTaskScheduler#repository" )
178 private RepositoryArchivaTaskScheduler scheduler;
179
180 @Inject
181 @Named( value = "fileLockManager#default" )
182 private FileLockManager fileLockManager;
183
184 private ApplicationContext applicationContext;
185
186
187 @Inject
188 public ArchivaDavResourceFactory( ApplicationContext applicationContext, ArchivaConfiguration archivaConfiguration )
189 throws PlexusSisuBridgeException
190 {
191 this.archivaConfiguration = archivaConfiguration;
192 this.applicationContext = applicationContext;
193
194 }
195
196 @PostConstruct
197 public void initialize() throws IOException
198 {
199
200 }
201
202
203 @Override
204 public DavResource createResource( final DavResourceLocator locator, final DavServletRequest request,
205 final DavServletResponse response )
206 throws DavException
207 {
208 final ArchivaDavResourceLocator archivaLocator = checkLocatorIsInstanceOfRepositoryLocator( locator );
209
210 final String sRepoId = archivaLocator.getRepositoryId();
211
212 RepositoryGroup repoGroup = repositoryRegistry.getRepositoryGroup(sRepoId);
213
214 final boolean isGroupRepo = repoGroup != null;
215
216 String activePrincipal = getActivePrincipal( request );
217
218 List<String> resourcesInAbsolutePath = new ArrayList<>();
219
220 boolean readMethod = WebdavMethodUtil.isReadMethod( request.getMethod() );
221 RepositoryRequestInfo repositoryRequestInfo = null;
222 DavResource resource;
223 if ( isGroupRepo )
224 {
225 if ( !readMethod )
226 {
227 throw new DavException( HttpServletResponse.SC_METHOD_NOT_ALLOWED,
228 "Write method not allowed for repository groups." );
229 }
230
231 log.debug( "Repository group '{}' accessed by '{}", repoGroup.getId(), activePrincipal );
232
233
234 if ( getLogicalResource( archivaLocator, null, true ).endsWith( "/" ) )
235 {
236 DavResource davResource =
237 getResourceFromGroup( request, archivaLocator,
238 repoGroup );
239
240 setHeaders( response, locator, davResource, true );
241
242 return davResource;
243
244 }
245 else
246 {
247
248
249
250 resource = processRepositoryGroup( request, archivaLocator, activePrincipal,
251 resourcesInAbsolutePath, repoGroup );
252 for (ManagedRepository repo : repoGroup.getRepositories() ) {
253 if (repo!=null) {
254 repositoryRequestInfo = repo.getRequestInfo();
255 break;
256 }
257 }
258 }
259 }
260 else
261 {
262
263
264
265
266 ManagedRepository repo = repositoryRegistry.getManagedRepository( sRepoId );
267 if (repo==null) {
268 throw new DavException( HttpServletResponse.SC_NOT_FOUND,
269 "Invalid repository: " + archivaLocator.getRepositoryId() );
270 }
271 ManagedRepositoryContent managedRepositoryContent = repo.getContent( );
272 if (managedRepositoryContent==null) {
273 log.error("Inconsistency detected. Repository content not found for '{}'", archivaLocator.getRepositoryId());
274 throw new DavException( HttpServletResponse.SC_NOT_FOUND,
275 "Invalid repository: " + archivaLocator.getRepositoryId() );
276 }
277
278 log.debug( "Managed repository '{}' accessed by '{}'", managedRepositoryContent.getId(), activePrincipal );
279
280 resource = processRepository( request, archivaLocator, activePrincipal, managedRepositoryContent,
281 repo);
282 repositoryRequestInfo = repo.getRequestInfo();
283 String logicalResource = getLogicalResource( archivaLocator, null, false );
284 resourcesInAbsolutePath.add(
285 Paths.get( managedRepositoryContent.getRepoRoot(), logicalResource ).toAbsolutePath().toString() );
286
287 }
288
289 String requestedResource = request.getRequestURI();
290
291
292
293 if ( ( repositoryRequestInfo.isMetadata( requestedResource ) || repositoryRequestInfo.isMetadataSupportFile(
294 requestedResource ) ) && isGroupRepo )
295 {
296
297 if ( isProjectReference( requestedResource ) )
298 {
299
300 ArchivaDavResource../org/apache/archiva/webdav/ArchivaDavResource.html#ArchivaDavResource">ArchivaDavResource res = (ArchivaDavResource) resource;
301 String newPath;
302 if (res.getAsset().hasParent())
303 {
304 newPath = res.getAsset( ).getParent( ).getPath( ) + "/maven-metadata-" + sRepoId + ".xml";
305 } else {
306 newPath = StringUtils.substringBeforeLast( res.getAsset().getPath(), "/" ) + "/maven-metadata-" + sRepoId + ".xml";;
307 }
308
309 if ( repositoryRequestInfo.isSupportFile( requestedResource ) )
310 {
311 String metadataChecksumPath = newPath + "." + StringUtils.substringAfterLast( requestedResource, "." );
312 StorageAsset metadataChecksum = repoGroup.getAsset( metadataChecksumPath );
313 if ( repoGroup.getAsset( metadataChecksumPath ).exists() )
314 {
315 LogicalResource logicalResource =
316 new LogicalResource( getLogicalResource( archivaLocator, null, false ) );
317
318 try
319 {
320 resource =
321 new ArchivaDavResource( metadataChecksum, logicalResource.getPath(), repoGroup,
322 request.getRemoteAddr(), activePrincipal, request.getDavSession(),
323 archivaLocator, this, mimeTypes, auditListeners, scheduler);
324 }
325 catch ( LayoutException e )
326 {
327 log.error("Incompatible layout: {}", e.getMessage(), e);
328 throw new DavException( 500, e );
329 }
330 }
331 }
332 else
333 {
334 if ( resourcesInAbsolutePath != null && resourcesInAbsolutePath.size() > 1 )
335 {
336
337 ArchivaRepositoryMetadata#ArchivaRepositoryMetadata">ArchivaRepositoryMetadata mergedMetadata = new ArchivaRepositoryMetadata();
338 for ( String resourceAbsPath : resourcesInAbsolutePath )
339 {
340 try
341 {
342 Path metadataFile = Paths.get( resourceAbsPath );
343 ArchivaRepositoryMetadata repoMetadata = MavenMetadataReader.read( metadataFile );
344 mergedMetadata = RepositoryMetadataMerge.merge( mergedMetadata, repoMetadata );
345 }
346 catch (XMLException e )
347 {
348 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
349 "Error occurred while reading metadata file." );
350 }
351 catch ( RepositoryMetadataException r )
352 {
353 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
354 "Error occurred while merging metadata file." );
355 }
356 }
357
358 try
359 {
360 StorageAsset resourceFile = writeMergedMetadataToFile( repoGroup, mergedMetadata, newPath );
361
362 LogicalResource logicalResource =
363 new LogicalResource( getLogicalResource( archivaLocator, null, false ) );
364
365 resource =
366 new ArchivaDavResource( resourceFile, logicalResource.getPath(), repoGroup,
367 request.getRemoteAddr(), activePrincipal,
368 request.getDavSession(), archivaLocator, this, mimeTypes,
369 auditListeners, scheduler);
370 }
371 catch ( RepositoryMetadataException r )
372 {
373 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
374 "Error occurred while writing metadata file." );
375 }
376 catch ( IOException ie )
377 {
378 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
379 "Error occurred while generating checksum files." );
380 }
381 catch ( LayoutException e )
382 {
383 log.error("Incompatible layout: {}", e.getMessage(), e);
384 throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Incompatible layout for repository "+repoGroup.getId());
385 }
386 }
387 }
388 }
389 }
390
391 setHeaders( response, locator, resource, false );
392
393
394 if ( resource.isCollection() && !request.getRequestURI().endsWith( "/" ) )
395 {
396 throw new BrowserRedirectException( resource.getHref() );
397 }
398 resource.addLockManager( lockManager );
399 return resource;
400 }
401
402 private DavResource processRepositoryGroup( final DavServletRequest request,
403 ArchivaDavResourceLocator archivaLocator,
404 String activePrincipal, List<String> resourcesInAbsolutePath,
405 RepositoryGroup repoGroup )
406 throws DavException
407 {
408 DavResource resource = null;
409 List<DavException> storedExceptions = new ArrayList<>();
410
411 String pathInfo = StringUtils.removeEnd( request.getPathInfo(), "/" );
412
413 String rootPath = StringUtils.substringBeforeLast( pathInfo, "/" );
414
415 String mergedIndexPath = "/";
416 if (repoGroup.supportsFeature( IndexCreationFeature.class )) {
417 mergedIndexPath = repoGroup.getFeature( IndexCreationFeature.class ).get().getIndexPath().getPath();
418 }
419
420 if ( StringUtils.endsWith( rootPath, mergedIndexPath ) )
421 {
422
423 String requestedFileName = StringUtils.substringAfterLast( pathInfo, "/" );
424 StorageAsset temporaryIndexDirectory =
425 buildMergedIndexDirectory( activePrincipal, request, repoGroup );
426 StorageAsset asset = temporaryIndexDirectory.resolve(requestedFileName);
427
428 try {
429 resource = new ArchivaDavResource( asset, requestedFileName, repoGroup,
430 request.getRemoteAddr(), activePrincipal, request.getDavSession(),
431 archivaLocator, this, mimeTypes, auditListeners, scheduler );
432 } catch (LayoutException e) {
433 log.error("Bad layout: {}", e.getMessage(), e);
434 throw new DavException(500, e);
435 }
436
437 }
438 else
439 {
440 for ( ManagedRepository repository : repoGroup.getRepositories() )
441 {
442 String repositoryId = repository.getId();
443 ManagedRepositoryContent managedRepositoryContent;
444 ManagedRepository managedRepository = repositoryRegistry.getManagedRepository( repositoryId );
445 if (managedRepository==null) {
446 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not find repository with id "+repositoryId );
447 }
448 managedRepositoryContent = managedRepository.getContent();
449 if (managedRepositoryContent==null) {
450 log.error("Inconsistency detected. Repository content not found for '{}'",repositoryId);
451 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not find repository content with id "+repositoryId );
452 }
453 try
454 {
455 DavResource updatedResource =
456 processRepository( request, archivaLocator, activePrincipal, managedRepositoryContent,
457 managedRepository );
458 if ( resource == null )
459 {
460 resource = updatedResource;
461 }
462
463 String logicalResource = getLogicalResource( archivaLocator, null, false );
464 if ( logicalResource.endsWith( "/" ) )
465 {
466 logicalResource = logicalResource.substring( 1 );
467 }
468 resourcesInAbsolutePath.add(
469 Paths.get( managedRepositoryContent.getRepoRoot(), logicalResource ).toAbsolutePath().toString() );
470 }
471 catch ( DavException e )
472 {
473 storedExceptions.add( e );
474 }
475 }
476 }
477 if ( resource == null )
478 {
479 if ( !storedExceptions.isEmpty() )
480 {
481
482 for ( DavException e : storedExceptions )
483 {
484 if ( 401 == e.getErrorCode() )
485 {
486 throw e;
487 }
488 }
489
490 throw new DavException( HttpServletResponse.SC_NOT_FOUND );
491 }
492 else
493 {
494 throw new DavException( HttpServletResponse.SC_NOT_FOUND );
495 }
496 }
497 return resource;
498 }
499
500 private String getLogicalResource( ArchivaDavResourceLocator archivaLocator, org.apache.archiva.repository.ManagedRepository managedRepository,
501 boolean useOrigResourcePath )
502 {
503
504
505 String layout = managedRepository == null ? "default" : managedRepository.getLayout();
506 RepositoryStorage repositoryStorage =
507 this.applicationContext.getBean( "repositoryStorage#" + layout, RepositoryStorage.class );
508 String path = repositoryStorage.getFilePath(
509 useOrigResourcePath ? archivaLocator.getOrigResourcePath() : archivaLocator.getResourcePath(),
510 managedRepository );
511 log.debug( "found path {} for resourcePath: '{}' with managedRepo '{}' and layout '{}'", path,
512 archivaLocator.getResourcePath(), managedRepository == null ? "null" : managedRepository.getId(),
513 layout );
514 return path;
515 }
516
517 private String evaluatePathWithVersion( ArchivaDavResourceLocator archivaLocator,
518 ManagedRepositoryContent managedRepositoryContent,
519 String contextPath )
520 throws DavException
521 {
522 String layout = managedRepositoryContent.getRepository() == null
523 ? "default"
524 : managedRepositoryContent.getRepository().getLayout();
525 RepositoryStorage repositoryStorage =
526 this.applicationContext.getBean( "repositoryStorage#" + layout, RepositoryStorage.class );
527 try
528 {
529 return repositoryStorage.getFilePathWithVersion( archivaLocator.getResourcePath(),
530 managedRepositoryContent );
531 }
532 catch ( RelocationException e )
533 {
534 String path = e.getPath();
535 log.debug( "Relocation to {}", path );
536
537 throw new BrowserRedirectException( addHrefPrefix( contextPath, path ), e.getRelocationType() );
538 }
539 catch (XMLException | IOException e )
540 {
541 log.error( e.getMessage(), e );
542 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
543 }
544 }
545
546 private DavResource processRepository( final DavServletRequest request, ArchivaDavResourceLocator archivaLocator,
547 String activePrincipal, ManagedRepositoryContent managedRepositoryContent,
548 org.apache.archiva.repository.ManagedRepository managedRepository )
549 throws DavException
550 {
551 DavResource resource = null;
552 if ( isAuthorized( request, managedRepositoryContent.getId() ) )
553 {
554 boolean readMethod = WebdavMethodUtil.isReadMethod( request.getMethod() );
555
556
557
558 String path = readMethod
559 ? evaluatePathWithVersion( archivaLocator, managedRepositoryContent, request.getContextPath() )
560 : getLogicalResource( archivaLocator, managedRepository, false );
561 if ( path.startsWith( "/" ) )
562 {
563 path = path.substring( 1 );
564 }
565 LogicalResource#LogicalResource">LogicalResource logicalResource = new LogicalResource( path );
566 StorageAsset repoAsset = managedRepository.getAsset( path );
567
568 try
569 {
570 resource =
571 new ArchivaDavResource( repoAsset, path, managedRepository,
572 request.getRemoteAddr(), activePrincipal, request.getDavSession(),
573 archivaLocator, this, mimeTypes, auditListeners, scheduler );
574 }
575 catch ( LayoutException e )
576 {
577 log.error("Incompatible layout: {}", e.getMessage(), e);
578 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
579 }
580
581 if ( WebdavMethodUtil.isReadMethod( request.getMethod() ) )
582 {
583 if ( archivaLocator.getHref( false ).endsWith( "/" ) && !repoAsset.isContainer() )
584 {
585
586 throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Resource does not exist" );
587 }
588 else
589 {
590 if ( !resource.isCollection() )
591 {
592 boolean previouslyExisted = repoAsset.exists();
593
594 boolean fromProxy = fetchContentFromProxies( managedRepository, request, logicalResource );
595
596 StorageAsset resourceAsset=null;
597
598
599 try
600 {
601
602
603
604 resourceAsset = managedRepository.getAsset( logicalResource.getPath() );
605 resource =
606 new ArchivaDavResource( resourceAsset, logicalResource.getPath(),
607 managedRepository,
608 request.getRemoteAddr(), activePrincipal,
609 request.getDavSession(), archivaLocator, this, mimeTypes,
610 auditListeners, scheduler );
611 }
612 catch ( LayoutException e )
613 {
614 if ( resourceAsset==null || !resourceAsset.exists() )
615 {
616 throw new DavException( HttpServletResponse.SC_NOT_FOUND, e );
617 }
618 }
619
620 if ( fromProxy )
621 {
622 String action = ( previouslyExisted ? AuditEvent.MODIFY_FILE : AuditEvent.CREATE_FILE )
623 + PROXIED_SUFFIX;
624
625 log.debug( "Proxied artifact '{}' in repository '{}' (current user '{}')",
626 resourceAsset.getName(), managedRepositoryContent.getId(), activePrincipal );
627
628 triggerAuditEvent( request.getRemoteAddr(), archivaLocator.getRepositoryId(),
629 logicalResource.getPath(), action, activePrincipal );
630 }
631
632 if ( !resourceAsset.exists() )
633 {
634 throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Resource does not exist" );
635 }
636 }
637 }
638 }
639
640 if ( request.getMethod().equals( HTTP_PUT_METHOD ) )
641 {
642 String resourcePath = logicalResource.getPath();
643 RepositoryRequestInfo repositoryRequestInfo = managedRepository.getRequestInfo();
644
645
646 if ( managedRepositoryContent.getRepository().getActiveReleaseSchemes().contains( ReleaseScheme.RELEASE ) && !repositoryRequestInfo.isMetadata(
647 resourcePath ) && !repositoryRequestInfo.isSupportFile( resourcePath ) )
648 {
649 ArtifactReference artifact = null;
650 try
651 {
652 artifact = managedRepositoryContent.toArtifactReference( resourcePath );
653
654 if ( !VersionUtil.isSnapshot( artifact.getVersion() ) )
655 {
656
657 if ( managedRepositoryContent.hasContent( artifact )
658 && managedRepositoryContent.getRepository().blocksRedeployments())
659 {
660 log.warn( "Overwriting released artifacts in repository '{}' is not allowed.",
661 managedRepositoryContent.getId() );
662 throw new DavException( HttpServletResponse.SC_CONFLICT,
663 "Overwriting released artifacts is not allowed." );
664 }
665 }
666 }
667 catch ( LayoutException e )
668 {
669 log.warn( "Artifact path '{}' is invalid.", resourcePath );
670 }
671 }
672
673
674
675
676
677
678
679
680 Path rootDirectory = Paths.get( managedRepositoryContent.getRepoRoot() );
681 Path destDir = rootDirectory.resolve( logicalResource.getPath() ).getParent();
682
683 if ( !Files.exists(destDir) )
684 {
685 try
686 {
687 Files.createDirectories( destDir );
688 }
689 catch ( IOException e )
690 {
691 log.error("Could not create directory {}: {}", destDir, e.getMessage(), e);
692 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not create directory "+destDir );
693 }
694 String relPath = PathUtil.getRelative( rootDirectory.toAbsolutePath().toString(), destDir );
695
696 log.debug( "Creating destination directory '{}' (current user '{}')", destDir.getFileName(),
697 activePrincipal );
698
699 triggerAuditEvent( request.getRemoteAddr(), managedRepositoryContent.getId(), relPath,
700 AuditEvent.CREATE_DIR, activePrincipal );
701 }
702 }
703 }
704 return resource;
705 }
706
707 @Override
708 public DavResource createResource( final DavResourceLocator locator, final DavSession davSession )
709 throws DavException
710 {
711 ArchivaDavResourceLocator archivaLocator = checkLocatorIsInstanceOfRepositoryLocator( locator );
712
713 ManagedRepositoryContent managedRepositoryContent;
714 ManagedRepository repo = repositoryRegistry.getManagedRepository( archivaLocator.getRepositoryId( ) );
715 if (repo==null) {
716 throw new DavException( HttpServletResponse.SC_NOT_FOUND,
717 "Invalid repository: " + archivaLocator.getRepositoryId() );
718 }
719 managedRepositoryContent = repo.getContent();
720 if (managedRepositoryContent==null) {
721 log.error("Inconsistency detected. Repository content not found for '{}'", archivaLocator.getRepositoryId());
722 throw new DavException( HttpServletResponse.SC_NOT_FOUND,
723 "Invalid repository: " + archivaLocator.getRepositoryId() );
724 }
725
726 DavResource resource = null;
727 String logicalResource = getLogicalResource( archivaLocator, repo, false );
728 if ( logicalResource.startsWith( "/" ) )
729 {
730 logicalResource = logicalResource.substring( 1 );
731 }
732 StorageAsset resourceAsset = repo.getAsset( logicalResource );
733 try
734 {
735 resource = new ArchivaDavResource( resourceAsset, logicalResource,
736 repo, davSession, archivaLocator,
737 this, mimeTypes, auditListeners, scheduler);
738 }
739 catch ( LayoutException e )
740 {
741 log.error( "Incompatible layout: {}", e.getMessage( ), e );
742 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
743 }
744
745 resource.addLockManager( lockManager );
746 return resource;
747 }
748
749 private boolean fetchContentFromProxies( ManagedRepository managedRepository, DavServletRequest request,
750 LogicalResource resource )
751 throws DavException
752 {
753 String path = resource.getPath();
754 if (!proxyRegistry.hasHandler(managedRepository.getType())) {
755 throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "No proxy handler found for repository type "+managedRepository.getType());
756 }
757 RepositoryRequestInfo repositoryRequestInfo = managedRepository.getRequestInfo();
758 RepositoryProxyHandler proxyHandler = proxyRegistry.getHandler(managedRepository.getType()).get(0);
759 if ( repositoryRequestInfo.isSupportFile( path ) )
760 {
761 StorageAsset proxiedFile = proxyHandler.fetchFromProxies( managedRepository, path );
762
763 return ( proxiedFile != null );
764 }
765
766
767 if ( "default".equals(repositoryRequestInfo.getLayout( path )) && repositoryRequestInfo.isMetadata( path ) )
768 {
769 return proxyHandler.fetchMetadataFromProxies( managedRepository, path ).isModified();
770 }
771
772
773 if ( repositoryRequestInfo.isArchetypeCatalog( path ) )
774 {
775
776 StorageAsset proxiedFile = proxyHandler.fetchFromProxies( managedRepository, path );
777
778 return ( proxiedFile != null );
779 }
780
781
782 try
783 {
784
785 ArtifactReference artifact = repositoryRequestInfo.toArtifactReference( path );
786
787 if ( artifact != null )
788 {
789 String repositoryLayout = managedRepository.getLayout();
790
791 RepositoryStorage repositoryStorage =
792 this.applicationContext.getBean( "repositoryStorage#" + repositoryLayout, RepositoryStorage.class );
793 repositoryStorage.applyServerSideRelocation( managedRepository, artifact );
794
795 StorageAsset proxiedFile = proxyHandler.fetchFromProxies( managedRepository, artifact );
796
797 resource.setPath( managedRepository.getContent().toPath( artifact ) );
798
799 log.debug( "Proxied artifact '{}:{}:{}'", artifact.getGroupId(), artifact.getArtifactId(),
800 artifact.getVersion() );
801
802 return ( proxiedFile != null );
803 }
804 }
805 catch ( LayoutException e )
806 {
807
808 }
809 catch ( ProxyDownloadException e )
810 {
811 log.error( e.getMessage(), e );
812 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
813 "Unable to fetch artifact resource." );
814 }
815 return false;
816 }
817
818
819
820 private void triggerAuditEvent( String remoteIP, String repositoryId, String resource, String action,
821 String principal )
822 {
823 AuditEventel/facets/AuditEvent.html#AuditEvent">AuditEvent event = new AuditEvent( repositoryId, principal, resource, action );
824 event.setRemoteIP( remoteIP );
825
826 for ( AuditListener listener : auditListeners )
827 {
828 listener.auditEvent( event );
829 }
830 }
831
832 @Override
833 public void addAuditListener( AuditListener listener )
834 {
835 this.auditListeners.add( listener );
836 }
837
838 @Override
839 public void clearAuditListeners()
840 {
841 this.auditListeners.clear();
842 }
843
844 @Override
845 public void removeAuditListener( AuditListener listener )
846 {
847 this.auditListeners.remove( listener );
848 }
849
850 private void setHeaders( DavServletResponse response, DavResourceLocator locator, DavResource resource,
851 boolean group )
852 {
853
854
855 if ( locator.getResourcePath().endsWith( "/maven-metadata.xml" ) || ( resource instanceof ArchivaDavResource
856 && ( ArchivaDavResource.class.cast( resource ).getAsset().isContainer() ) ) )
857 {
858 response.setHeader( "Pragma", "no-cache" );
859 response.setHeader( "Cache-Control", "no-cache" );
860 response.setDateHeader( "Last-Modified", new Date().getTime() );
861 }
862
863
864 else if ( locator.getResourcePath().endsWith( "/maven-metadata.xml" ) || (
865 resource instanceof ArchivaVirtualDavResource && ( Files.isDirectory(Paths.get(
866 ArchivaVirtualDavResource.class.cast( resource ).getLogicalResource() )) ) ) )
867 {
868 response.setHeader( "Pragma", "no-cache" );
869 response.setHeader( "Cache-Control", "no-cache" );
870 response.setDateHeader( "Last-Modified", new Date().getTime() );
871 }
872 else if ( group )
873 {
874 if ( resource instanceof ArchivaVirtualDavResource )
875 {
876
877 response.setDateHeader( "Last-Modified", new Date().getTime() );
878 }
879 }
880 else
881 {
882
883 response.setDateHeader( "Last-Modified", resource.getModificationTime() );
884 }
885
886 }
887
888 private ArchivaDavResourceLocator checkLocatorIsInstanceOfRepositoryLocator( DavResourceLocator locator )
889 throws DavException
890 {
891 if ( !( locator instanceof ArchivaDavResourceLocator ) )
892 {
893 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
894 "Locator does not implement RepositoryLocator" );
895 }
896
897
898 if ( locator.getResourcePath().startsWith( ArchivaDavResource.HIDDEN_PATH_PREFIX ) )
899 {
900 throw new DavException( HttpServletResponse.SC_NOT_FOUND );
901 }
902
903 ArchivaDavResourceLocatoriva/webdav/ArchivaDavResourceLocator.html#ArchivaDavResourceLocator">ArchivaDavResourceLocator archivaLocator = (ArchivaDavResourceLocator) locator;
904
905
906 if ( StringUtils.isEmpty( archivaLocator.getRepositoryId() ) )
907 {
908 throw new DavException( HttpServletResponse.SC_NO_CONTENT );
909 }
910 return archivaLocator;
911 }
912
913 private String addHrefPrefix( String contextPath, String path ) {
914 String prefix = archivaConfiguration.getConfiguration().getWebapp().getUi().getApplicationUrl();
915 if (prefix == null || prefix.isEmpty()) {
916 prefix = contextPath;
917 }
918 return prefix + ( StringUtils.startsWith( path, "/" ) ? "" :
919 ( StringUtils.endsWith( prefix, "/" ) ? "" : "/" ) )
920 + path;
921 }
922
923 public void setProxyRegistry(ProxyRegistry proxyRegistry) {
924 this.proxyRegistry = proxyRegistry;
925 }
926
927 public ProxyRegistry getProxyRegistry() {
928 return this.proxyRegistry;
929 }
930
931 private static class LogicalResource
932 {
933 private String path;
934
935 public LogicalResource( String path )
936 {
937 this.path = path;
938 }
939
940 public String getPath()
941 {
942 return path;
943 }
944
945 public void setPath( String path )
946 {
947 this.path = path;
948 }
949 }
950
951 protected boolean isAuthorized( DavServletRequest request, String repositoryId )
952 throws DavException
953 {
954 try
955 {
956 AuthenticationResult result = httpAuth.getAuthenticationResult( request, null );
957 SecuritySession securitySession = httpAuth.getSecuritySession( request.getSession( true ) );
958
959 return servletAuth.isAuthenticated( request, result )
960 && servletAuth.isAuthorized( request, securitySession, repositoryId,
961 WebdavMethodUtil.getMethodPermission( request.getMethod() ) );
962 }
963 catch ( AuthenticationException e )
964 {
965
966 String guest = UserManager.GUEST_USERNAME;
967 try
968 {
969 if ( servletAuth.isAuthorized( guest,
970 ( (ArchivaDavResourceLocator) request.getRequestLocator() ).getRepositoryId(),
971 WebdavMethodUtil.getMethodPermission( request.getMethod() ) ) )
972 {
973 return true;
974 }
975 }
976 catch ( UnauthorizedException ae )
977 {
978 throw new UnauthorizedDavException( repositoryId,
979 "You are not authenticated and authorized to access any repository." );
980 }
981
982 throw new UnauthorizedDavException( repositoryId, "You are not authenticated" );
983 }
984 catch ( MustChangePasswordException e )
985 {
986 throw new UnauthorizedDavException( repositoryId, "You must change your password." );
987 }
988 catch ( AccountLockedException e )
989 {
990 throw new UnauthorizedDavException( repositoryId, "User account is locked." );
991 }
992 catch ( AuthorizationException e )
993 {
994 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
995 "Fatal Authorization Subsystem Error." );
996 }
997 catch ( UnauthorizedException e )
998 {
999 throw new UnauthorizedDavException( repositoryId, e.getMessage() );
1000 }
1001 }
1002
1003 private DavResource getResourceFromGroup( DavServletRequest request,
1004 ArchivaDavResourceLocator locator,
1005 RepositoryGroup repositoryGroup )
1006 throws DavException
1007 {
1008 final String id = repositoryGroup.getId();
1009 final List<ManagedRepository> repositories = repositoryGroup.getRepositories();
1010 if ( repositories == null
1011 || repositories.isEmpty() )
1012 {
1013 try {
1014 return new ArchivaDavResource( repositoryGroup.getAsset("/"), "groups/" + id, null,
1015 request.getDavSession(), locator, this, mimeTypes, auditListeners, scheduler);
1016 } catch (LayoutException e) {
1017 log.error("Bad repository layout: {}", e.getMessage(), e);
1018 throw new DavException(500, e);
1019 }
1020 }
1021 List<StorageAsset> mergedRepositoryContents = new ArrayList<>();
1022
1023 ManagedRepository firstRepo = repositories.get( 0 );
1024
1025 String path = getLogicalResource( locator, firstRepo, false );
1026 if ( path.startsWith( "/" ) )
1027 {
1028 path = path.substring( 1 );
1029 }
1030 LogicalResource#LogicalResource">LogicalResource logicalResource = new LogicalResource( path );
1031
1032
1033
1034
1035
1036
1037 String activePrincipal = getActivePrincipal( request );
1038
1039 boolean allow = isAllowedToContinue( request, repositories, activePrincipal );
1040
1041
1042 String pathInfo = StringUtils.removeEnd( request.getPathInfo(), "/" );
1043 String mergedIndexPath = "/";
1044 if (repositoryGroup.supportsFeature( IndexCreationFeature.class )) {
1045 IndexCreationFeature indexCreationFeature = repositoryGroup.getFeature( IndexCreationFeature.class ).get();
1046 mergedIndexPath = indexCreationFeature.getIndexPath().getPath();
1047 }
1048
1049 if ( allow )
1050 {
1051
1052 if ( StringUtils.endsWith( pathInfo, mergedIndexPath ) )
1053 {
1054 StorageAsset mergedRepoDirPath =
1055 buildMergedIndexDirectory( activePrincipal, request, repositoryGroup );
1056 mergedRepositoryContents.add( mergedRepoDirPath );
1057 }
1058 else
1059 {
1060 if ( StringUtils.equalsIgnoreCase( pathInfo, "/" + id ) )
1061 {
1062 Path tmpDirectory = Paths.get( SystemUtils.getJavaIoTmpDir().toString(),
1063 id,
1064 mergedIndexPath );
1065 if ( !Files.exists(tmpDirectory) )
1066 {
1067 synchronized ( tmpDirectory.toAbsolutePath().toString() )
1068 {
1069 if ( !Files.exists(tmpDirectory) )
1070 {
1071 try
1072 {
1073 Files.createDirectories( tmpDirectory );
1074 }
1075 catch ( IOException e )
1076 {
1077 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not create direcotory "+tmpDirectory );
1078 }
1079 }
1080 }
1081 }
1082 try {
1083 FilesystemStoragelesystemStorage.html#FilesystemStorage">FilesystemStorage storage = new FilesystemStorage(tmpDirectory.getParent(), new DefaultFileLockManager());
1084 mergedRepositoryContents.add( storage.getAsset("") );
1085 } catch (IOException e) {
1086 throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not create storage for " + tmpDirectory);
1087 }
1088 }
1089 for ( ManagedRepository repo : repositories )
1090 {
1091 ManagedRepositoryContent managedRepository = null;
1092 if (repo == null) {
1093 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1094 "Invalid managed repository <" + repo.getId() + ">");
1095 }
1096 managedRepository = repo.getContent();
1097 if (managedRepository==null) {
1098 log.error("Inconsistency detected. Repository content not found for '{}'",repo.getId());
1099 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1100 "Invalid managed repository <" + repo.getId() + ">");
1101 }
1102
1103 StorageAsset resourceFile = repo.getAsset(logicalResource.getPath());
1104 if ( resourceFile.exists() && managedRepository.getRepository().supportsFeature( IndexCreationFeature.class ))
1105 {
1106
1107 IndexCreationFeature idf = managedRepository.getRepository().getFeature(IndexCreationFeature.class).get();
1108 StorageAsset repoIndexDirectory = idf.getLocalIndexPath();
1109 if ( !StringUtils.equals( FilenameUtils.normalize( repoIndexDirectory.getPath() ),
1110 FilenameUtils.normalize( logicalResource.getPath() ) ) )
1111 {
1112
1113 if ( httpAuth.getSecuritySession( request.getSession( true ) ) != null )
1114 {
1115 try
1116 {
1117 if ( isAuthorized( request, repo.getId() ) )
1118 {
1119 mergedRepositoryContents.add( resourceFile );
1120 log.debug( "Repository '{}' accessed by '{}'", repo.getId(), activePrincipal );
1121 }
1122 }
1123 catch ( DavException e )
1124 {
1125
1126
1127 log.debug( "Skipping repository '{}' for user '{}': {}", managedRepository,
1128 activePrincipal, e.getMessage() );
1129
1130 }
1131
1132 }
1133 else
1134 {
1135
1136 try
1137 {
1138 if ( servletAuth.isAuthorized( activePrincipal, repo.getId(),
1139 WebdavMethodUtil.getMethodPermission(
1140 request.getMethod() ) ) )
1141 {
1142 mergedRepositoryContents.add( resourceFile );
1143 log.debug( "Repository '{}' accessed by '{}'", repo.getId(), activePrincipal );
1144 }
1145 }
1146 catch ( UnauthorizedException e )
1147 {
1148
1149
1150 log.debug( "Skipping repository '{}' for user '{}': {}", managedRepository,
1151 activePrincipal, e.getMessage() );
1152
1153 }
1154 }
1155 }
1156 }
1157 }
1158 }
1159 }
1160 else
1161 {
1162 throw new UnauthorizedDavException( locator.getRepositoryId(), "User not authorized." );
1163 }
1164
1165 ArchivaVirtualDavResource resource =
1166 new ArchivaVirtualDavResource( mergedRepositoryContents, logicalResource.getPath(), mimeTypes, locator,
1167 this );
1168
1169
1170 if ( resource.isCollection() && !request.getRequestURI().endsWith( "/" ) )
1171 {
1172 throw new BrowserRedirectException( resource.getHref() );
1173 }
1174
1175 return resource;
1176 }
1177
1178 protected String getActivePrincipal( DavServletRequest request )
1179 {
1180 User sessionUser = httpAuth.getSessionUser( request.getSession() );
1181 return sessionUser != null ? sessionUser.getUsername() : UserManager.GUEST_USERNAME;
1182 }
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192 private boolean isAllowedToContinue( DavServletRequest request, List<ManagedRepository> repositories, String activePrincipal )
1193 {
1194
1195
1196 if ( repositories == null || repositories.isEmpty() )
1197 {
1198 return true;
1199 }
1200
1201 boolean allow = false;
1202
1203
1204 if ( httpAuth.getSecuritySession( request.getSession() ) != null )
1205 {
1206 for ( ManagedRepository repository : repositories )
1207 {
1208 try
1209 {
1210 if ( isAuthorized( request, repository.getId() ) )
1211 {
1212 allow = true;
1213 break;
1214 }
1215 }
1216 catch ( DavException e )
1217 {
1218 continue;
1219 }
1220 }
1221 }
1222 else
1223 {
1224 for ( ManagedRepository repository : repositories )
1225 {
1226 try
1227 {
1228 if ( servletAuth.isAuthorized( activePrincipal, repository.getId(),
1229 WebdavMethodUtil.getMethodPermission( request.getMethod() ) ) )
1230 {
1231 allow = true;
1232 break;
1233 }
1234 }
1235 catch ( UnauthorizedException e )
1236 {
1237 continue;
1238 }
1239 }
1240 }
1241
1242 return allow;
1243 }
1244
1245 private StorageAsset writeMergedMetadataToFile( RepositoryGroup repoGroup, ArchivaRepositoryMetadata mergedMetadata, String outputFilename )
1246 throws RepositoryMetadataException, IOException
1247 {
1248 StorageAsset asset = repoGroup.addAsset( outputFilename, false );
1249 OutputStream stream = asset.getWriteStream( true );
1250 OutputStreamWriter sw = new OutputStreamWriter( stream, "UTF-8" );
1251 RepositoryMetadataWriter.write( mergedMetadata, sw );
1252
1253 createChecksumFiles( repoGroup, outputFilename );
1254 return asset;
1255 }
1256
1257
1258 private void createChecksumFiles(RepositoryGroup repo, String path) {
1259 List<ChecksumAlgorithm> algorithms = ChecksumUtil.getAlgorithms( archivaConfiguration.getConfiguration( ).getArchivaRuntimeConfiguration( ).getChecksumTypes( ) );
1260 List<OutputStream> outStreams = algorithms.stream( ).map( algo -> {
1261 String ext = algo.getDefaultExtension( );
1262 try
1263 {
1264 return repo.getAsset( path + "." + ext ).getWriteStream( true );
1265 }
1266 catch ( IOException e )
1267 {
1268 e.printStackTrace( );
1269 return null;
1270 }
1271 } ).filter( Objects::nonNull ).collect( Collectors.toList( ) );
1272 try
1273 {
1274 StreamingChecksum.updateChecksums( repo.getAsset(path).getReadStream(), algorithms, outStreams );
1275 }
1276 catch ( IOException e )
1277 {
1278 e.printStackTrace( );
1279 }
1280 }
1281
1282
1283
1284 private boolean isProjectReference( String requestedResource )
1285 {
1286 try
1287 {
1288 metadataTools.toVersionedReference( requestedResource );
1289 return false;
1290 }
1291 catch ( RepositoryMetadataException re )
1292 {
1293 return true;
1294 }
1295 }
1296
1297 protected StorageAsset buildMergedIndexDirectory( String activePrincipal,
1298 DavServletRequest request,
1299 RepositoryGroup repositoryGroup )
1300 throws DavException
1301 {
1302
1303 try
1304 {
1305 final List<ManagedRepository> repositories = repositoryGroup.getRepositories();
1306 HttpSession session = request.getSession();
1307
1308 @SuppressWarnings( "unchecked" ) Map<String, TemporaryGroupIndex> temporaryGroupIndexMap =
1309 (Map<String, TemporaryGroupIndex>) session.getAttribute(
1310 TemporaryGroupIndexSessionCleaner.TEMPORARY_INDEX_SESSION_KEY );
1311 if ( temporaryGroupIndexMap == null )
1312 {
1313 temporaryGroupIndexMap = new HashMap<>();
1314 }
1315
1316 final String id = repositoryGroup.getId();
1317 TemporaryGroupIndex tmp = temporaryGroupIndexMap.get(id);
1318
1319 if ( tmp != null && tmp.getDirectory() != null && tmp.getDirectory().exists())
1320 {
1321 if ( System.currentTimeMillis() - tmp.getCreationTime() > (
1322 repositoryGroup.getMergedIndexTTL() * 60 * 1000 ) )
1323 {
1324 log.debug( MarkerFactory.getMarker( "group.merged.index" ),
1325 "tmp group index '{}' is too old so delete it", id);
1326 indexMerger.cleanTemporaryGroupIndex( tmp );
1327 }
1328 else
1329 {
1330 log.debug( MarkerFactory.getMarker( "group.merged.index" ),
1331 "merged index for group '{}' found in cache", id);
1332 return tmp.getDirectory();
1333 }
1334 }
1335
1336 Set<String> authzRepos = new HashSet<String>();
1337
1338 String permission = WebdavMethodUtil.getMethodPermission( request.getMethod() );
1339
1340 for ( ManagedRepository repository : repositories )
1341 {
1342 try
1343 {
1344 if ( servletAuth.isAuthorized( activePrincipal, repository.getId(), permission ) )
1345 {
1346 authzRepos.add( repository.getId() );
1347 authzRepos.addAll( this.repositorySearch.getRemoteIndexingContextIds( repository.getId() ) );
1348 }
1349 }
1350 catch ( UnauthorizedException e )
1351 {
1352
1353
1354 log.debug( "Skipping repository '{}' for user '{}': {}", repository, activePrincipal,
1355 e.getMessage() );
1356 }
1357
1358 }
1359
1360 log.info( "generate temporary merged index for repository group '{}' for repositories '{}'",
1361 id, authzRepos );
1362
1363 IndexCreationFeature indexCreationFeature = repositoryGroup.getFeature( IndexCreationFeature.class ).get();
1364 Path indexPath = indexCreationFeature.getLocalIndexPath().getFilePath();
1365 if (indexPath!=null)
1366 {
1367 Path tempRepoFile = Files.createTempDirectory( "temp" );
1368 tempRepoFile.toFile( ).deleteOnExit( );
1369 FilesystemStoragelesystemStorage.html#FilesystemStorage">FilesystemStorage storage = new FilesystemStorage(tempRepoFile, new DefaultFileLockManager());
1370 StorageAsset tmpAsset = storage.getAsset("");
1371
1372 IndexMergerRequest indexMergerRequest =
1373 new IndexMergerRequest( authzRepos, true, id,
1374 indexPath.toString( ),
1375 repositoryGroup.getMergedIndexTTL( ) ).mergedIndexDirectory(
1376 tmpAsset ).temporary( true );
1377
1378 MergedRemoteIndexesTaskRequest taskRequest =
1379 new MergedRemoteIndexesTaskRequest( indexMergerRequest, indexMerger );
1380
1381 MergedRemoteIndexesTaskgedRemoteIndexesTask.html#MergedRemoteIndexesTask">MergedRemoteIndexesTask job = new MergedRemoteIndexesTask( taskRequest );
1382
1383 ArchivaIndexingContext indexingContext = job.execute( ).getIndexingContext( );
1384
1385 StorageAsset mergedRepoDir = indexingContext.getPath( );
1386 TemporaryGroupIndex temporaryGroupIndex =
1387 new TemporaryGroupIndex( mergedRepoDir, indexingContext.getId( ), id,
1388 repositoryGroup.getMergedIndexTTL( ) )
1389 .setCreationTime( new Date( ).getTime( ) );
1390 temporaryGroupIndexMap.put( id, temporaryGroupIndex );
1391 session.setAttribute( TemporaryGroupIndexSessionCleaner.TEMPORARY_INDEX_SESSION_KEY,
1392 temporaryGroupIndexMap );
1393 return mergedRepoDir;
1394 } else {
1395 log.error("Local index path for repository group {} does not exist.", repositoryGroup.getId());
1396 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
1397 }
1398 }
1399 catch ( RepositorySearchException e )
1400 {
1401 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
1402 }
1403 catch ( IndexMergerException e )
1404 {
1405 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
1406 }
1407 catch ( IOException e )
1408 {
1409 throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
1410 }
1411 }
1412
1413
1414 public void setServletAuth( ServletAuthenticator servletAuth )
1415 {
1416 this.servletAuth = servletAuth;
1417 }
1418
1419 public void setHttpAuth( HttpAuthenticator httpAuth )
1420 {
1421 this.httpAuth = httpAuth;
1422 }
1423
1424 public void setScheduler( RepositoryArchivaTaskScheduler scheduler )
1425 {
1426 this.scheduler = scheduler;
1427 }
1428
1429 public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration )
1430 {
1431 this.archivaConfiguration = archivaConfiguration;
1432 }
1433
1434 public RemoteRepositoryAdmin getRemoteRepositoryAdmin()
1435 {
1436 return remoteRepositoryAdmin;
1437 }
1438
1439 public void setRemoteRepositoryAdmin( RemoteRepositoryAdmin remoteRepositoryAdmin )
1440 {
1441 this.remoteRepositoryAdmin = remoteRepositoryAdmin;
1442 }
1443
1444 public ManagedRepositoryAdmin getManagedRepositoryAdmin()
1445 {
1446 return managedRepositoryAdmin;
1447 }
1448
1449 public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin )
1450 {
1451 this.managedRepositoryAdmin = managedRepositoryAdmin;
1452 }
1453
1454 public RepositoryRegistry getRepositoryRegistry( )
1455 {
1456 return repositoryRegistry;
1457 }
1458
1459 public void setRepositoryRegistry( RepositoryRegistry repositoryRegistry )
1460 {
1461 this.repositoryRegistry = repositoryRegistry;
1462 }
1463 }