From 79cc18ce7052c90339c8b17e9adff321e8cb3246 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Thu, 18 Jan 2007 20:39:19 +0000 Subject: [PATCH] * Upgraded webdav server to use new plexus-webdav with ability to override logic and correct flaws found in webdav servers. * Added ProxiedDavServer component (used by plexus-webdav) to make /repository/ access proxied. * Upgraded plexus, used [MRM-264] as baseline, but many more changes were needed. * Plexus upgrade broken JSTL's taglib everywhere, corrected by moving away from that taglib. * Created GroupIdLink tag following webwork guidelines for UI component. * Fixed AuditLog. git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@497563 13f79535-47bb-0310-9956-ffa450edef68 --- archiva-cli/pom.xml | 2 +- archiva-converter/pom.xml | 10 + archiva-core/pom.xml | 14 +- .../archiva/proxy/DefaultProxyManager.java | 257 --------------- .../archiva/proxy/ProxiedRepositoryGroup.java | 93 ------ .../maven/archiva/proxy/ProxyManager.java | 64 ---- archiva-plexus-application/pom.xml | 2 +- .../src/conf/application.xml | 2 +- archiva-plexus-runtime/pom.xml | 6 +- archiva-security/pom.xml | 4 + archiva-webapp/pom.xml | 30 +- .../maven/archiva/web/action/ProxyAction.java | 130 -------- .../archiva/web/repository/AuditLog.java | 137 ++++++++ .../web/repository/ProxiedDavServer.java | 198 ++++++++++++ .../web/repository/RepositoryServlet.java | 234 ++++++++++++++ .../web/servlet/AbstractPlexusServlet.java | 67 ---- .../web/servlet/PlexusComponentServlet.java | 131 -------- .../archiva/web/servlet/PlexusServlet.java | 49 --- .../servlet/repository/RepositoryAccess.java | 303 ------------------ .../repository/RepositoryException.java | 51 --- .../servlet/repository/RepositoryMapping.java | 92 ------ .../servlet/repository/RepositoryRequest.java | 80 ----- .../maven/archiva/web/tags/GroupIdLink.java | 148 +++++++++ .../archiva/web/tags/GroupIdLinkTag.java | 100 ++++++ .../resources/META-INF/plexus/application.xml | 37 +-- .../src/main/resources/META-INF/taglib.tld | 40 +++ archiva-webapp/src/main/resources/xwork.xml | 10 - .../WEB-INF/jsp/admin/managedRepositories.jsp | 4 +- .../webapp/WEB-INF/jsp/browseArtifact.jsp | 19 +- .../main/webapp/WEB-INF/jsp/browseGroup.jsp | 26 +- .../WEB-INF/jsp/include/artifactInfo.jspf | 20 +- .../webapp/WEB-INF/tags/showArtifactLink.tag | 23 +- .../src/main/webapp/WEB-INF/web.xml | 10 +- .../repository/RepositoryAccessTest.java | 83 ----- pom.xml | 40 ++- src/site/apt/guides/getting-started/index.apt | 2 +- 36 files changed, 976 insertions(+), 1542 deletions(-) delete mode 100644 archiva-core/src/main/java/org/apache/maven/archiva/proxy/DefaultProxyManager.java delete mode 100644 archiva-core/src/main/java/org/apache/maven/archiva/proxy/ProxiedRepositoryGroup.java delete mode 100644 archiva-core/src/main/java/org/apache/maven/archiva/proxy/ProxyManager.java delete mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/ProxyAction.java create mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/AuditLog.java create mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java create mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java delete mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/AbstractPlexusServlet.java delete mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/PlexusComponentServlet.java delete mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/PlexusServlet.java delete mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryAccess.java delete mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryException.java delete mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryMapping.java delete mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryRequest.java create mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/GroupIdLink.java create mode 100644 archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/GroupIdLinkTag.java create mode 100644 archiva-webapp/src/main/resources/META-INF/taglib.tld delete mode 100644 archiva-webapp/src/test/java/org/apache/maven/archiva/web/servlet/repository/RepositoryAccessTest.java diff --git a/archiva-cli/pom.xml b/archiva-cli/pom.xml index bc0f3f369..17019b0bd 100644 --- a/archiva-cli/pom.xml +++ b/archiva-cli/pom.xml @@ -37,7 +37,7 @@ org.codehaus.plexus plexus-cli - 1.0-SNAPSHOT + 1.0 commons-lang diff --git a/archiva-converter/pom.xml b/archiva-converter/pom.xml index 314e25c4b..7eabccb9e 100644 --- a/archiva-converter/pom.xml +++ b/archiva-converter/pom.xml @@ -33,6 +33,10 @@ org.codehaus.plexus plexus-utils + + org.codehaus.plexus + plexus-component-api + org.apache.maven maven-artifact @@ -54,5 +58,11 @@ commons-io commons-io + + + org.codehaus.plexus + plexus-container-default + test + diff --git a/archiva-core/pom.xml b/archiva-core/pom.xml index 0844a86dd..91f0f8eca 100644 --- a/archiva-core/pom.xml +++ b/archiva-core/pom.xml @@ -49,20 +49,30 @@ org.apache.maven.archiva archiva-reports-standard + + org.codehaus.plexus + plexus-component-api + org.codehaus.plexus plexus-quartz - 1.0-alpha-2 + 1.0-alpha-4-SNAPSHOT org.codehaus.plexus plexus-taskqueue - 1.0-alpha-4 + 1.0-alpha-6-SNAPSHOT commons-lang commons-lang + + + org.codehaus.plexus + plexus-container-default + test + diff --git a/archiva-core/src/main/java/org/apache/maven/archiva/proxy/DefaultProxyManager.java b/archiva-core/src/main/java/org/apache/maven/archiva/proxy/DefaultProxyManager.java deleted file mode 100644 index 66df019de..000000000 --- a/archiva-core/src/main/java/org/apache/maven/archiva/proxy/DefaultProxyManager.java +++ /dev/null @@ -1,257 +0,0 @@ -package org.apache.maven.archiva.proxy; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.apache.commons.lang.StringUtils; -import org.apache.maven.archiva.configuration.Configuration; -import org.apache.maven.archiva.configuration.ConfigurationChangeException; -import org.apache.maven.archiva.configuration.ConfigurationChangeListener; -import org.apache.maven.archiva.configuration.ConfigurationStore; -import org.apache.maven.archiva.configuration.ConfigurationStoreException; -import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory; -import org.apache.maven.archiva.configuration.InvalidConfigurationException; -import org.apache.maven.archiva.configuration.ProxiedRepositoryConfiguration; -import org.apache.maven.archiva.configuration.Proxy; -import org.apache.maven.archiva.configuration.RepositoryConfiguration; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.wagon.ResourceDoesNotExistException; -import org.apache.maven.wagon.proxy.ProxyInfo; -import org.codehaus.plexus.logging.AbstractLogEnabled; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * Default implementation of the proxy manager that bridges the repository configuration classes to the proxy API. This - * class is not thread safe (due to the request handler being a non-thread safe requirement). - * - * @author Brett Porter - * @todo we should be able to configure "views" that sit in front of this (ie, prefix = /legacy, appears as layout maven-1.x, path gets translated before being passed on) - * @plexus.component instantiation-strategy="per-lookup" - */ -public class DefaultProxyManager - extends AbstractLogEnabled - implements ProxyManager, ConfigurationChangeListener -{ - /** - * @plexus.requirement - */ - private ConfigurationStore configurationStore; - - /** - * @plexus.requirement role="org.apache.maven.archiva.proxy.ProxyRequestHandler" - * @todo seems to be a bug in qdox that the role above is required - */ - private ProxyRequestHandler requestHandler; - - /** - * @plexus.requirement - */ - private ConfiguredRepositoryFactory repositoryFactory; - - /** - * The proxy groups for each managed repository. - */ - private static Map/**/ proxyGroups; - - /** - * The default proxy group/managed repository. - */ - private static ProxiedRepositoryGroup defaultProxyGroup; - - public File get( String path ) - throws ProxyException, ResourceDoesNotExistException - { - assert path.startsWith( "/" ); - - Map groups = getProxyGroups(); - - ProxiedRepositoryGroup proxyGroup = parseRepositoryId( path, groups ); - - String repositoryPath = path; - if ( proxyGroup == null ) - { - if ( defaultProxyGroup != null ) - { - proxyGroup = defaultProxyGroup; - } - else - { - throw new ResourceDoesNotExistException( "No repositories exist under the path: " + path ); - } - } - else - { - String id = proxyGroup.getManagedRepository().getId(); - getLogger().debug( "requesting " + repositoryPath + " from repository '" + id + "'" ); - repositoryPath = repositoryPath.substring( id.length() + 2 ); - } - - return requestHandler.get( repositoryPath, proxyGroup.getProxiedRepositories(), - proxyGroup.getManagedRepository(), proxyGroup.getWagonProxy() ); - } - - public File getAlways( String path ) - throws ProxyException, ResourceDoesNotExistException - { - assert path.startsWith( "/" ); - - Map groups = getProxyGroups(); - - ProxiedRepositoryGroup proxyGroup = parseRepositoryId( path, groups ); - - String repositoryPath = path; - if ( proxyGroup == null ) - { - if ( defaultProxyGroup != null ) - { - proxyGroup = defaultProxyGroup; - } - else - { - throw new ResourceDoesNotExistException( "No repositories exist under the path: " + path ); - } - } - else - { - repositoryPath = repositoryPath.substring( proxyGroup.getManagedRepository().getId().length() + 2 ); - } - - return requestHandler.getAlways( repositoryPath, proxyGroup.getProxiedRepositories(), - proxyGroup.getManagedRepository(), proxyGroup.getWagonProxy() ); - } - - private Configuration getConfiguration() - throws ProxyException - { - Configuration configuration; - try - { - configuration = configurationStore.getConfigurationFromStore(); - - configurationStore.addChangeListener( this ); - } - catch ( ConfigurationStoreException e ) - { - throw new ProxyException( "Error reading configuration, unable to proxy any requests: " + e.getMessage(), - e ); - } - return configuration; - } - - private Map getProxyGroups() - throws ProxyException, ResourceDoesNotExistException - { - if ( proxyGroups == null ) - { - Map groups = new HashMap(); - - Configuration configuration = getConfiguration(); - - ProxyInfo wagonProxy = createWagonProxy( configuration.getProxy() ); - - for ( Iterator i = configuration.getRepositories().iterator(); i.hasNext(); ) - { - RepositoryConfiguration repository = (RepositoryConfiguration) i.next(); - ArtifactRepository managedRepository = repositoryFactory.createRepository( repository ); - List proxiedRepositories = getProxiedRepositoriesForManagedRepository( - configuration.getProxiedRepositories(), repository.getId() ); - - if ( !proxiedRepositories.isEmpty() ) - { - groups.put( repository.getId(), - new ProxiedRepositoryGroup( proxiedRepositories, managedRepository, wagonProxy ) ); - } - } - - // TODO: ability to configure default proxy separately! - - if ( groups.size() == 1 ) - { - defaultProxyGroup = (ProxiedRepositoryGroup) groups.values().iterator().next(); - } - - proxyGroups = groups; - } - return proxyGroups; - } - - private List getProxiedRepositoriesForManagedRepository( List proxiedRepositories, String id ) - { - List repositories = new ArrayList(); - for ( Iterator i = proxiedRepositories.iterator(); i.hasNext(); ) - { - ProxiedRepositoryConfiguration config = (ProxiedRepositoryConfiguration) i.next(); - - if ( config.getManagedRepository().equals( id ) ) - { - repositories.add( repositoryFactory.createProxiedRepository( config ) ); - } - } - return repositories; - } - - private static ProxiedRepositoryGroup parseRepositoryId( String path, Map groups ) - throws ProxyException, ResourceDoesNotExistException - { - ProxiedRepositoryGroup group = null; - - for ( Iterator i = groups.entrySet().iterator(); i.hasNext() && group == null; ) - { - Map.Entry entry = (Map.Entry) i.next(); - - if ( path.startsWith( "/" + entry.getKey() + "/" ) ) - { - group = (ProxiedRepositoryGroup) entry.getValue(); - } - } - - return group; - } - - private static ProxyInfo createWagonProxy( Proxy proxy ) - { - ProxyInfo proxyInfo = null; - if ( proxy != null && StringUtils.isNotEmpty( proxy.getHost() ) ) - { - proxyInfo = new ProxyInfo(); - proxyInfo.setHost( proxy.getHost() ); - proxyInfo.setPort( proxy.getPort() ); - proxyInfo.setUserName( proxy.getUsername() ); - proxyInfo.setPassword( proxy.getPassword() ); - proxyInfo.setNonProxyHosts( proxy.getNonProxyHosts() ); - proxyInfo.setType( proxy.getProtocol() ); - } - return proxyInfo; - } - - public void notifyOfConfigurationChange( Configuration configuration ) - throws InvalidConfigurationException, ConfigurationChangeException - { - // reinit - proxyGroups = null; - defaultProxyGroup = null; - getLogger().debug( "Re-initialising proxy configuration" ); - } -} diff --git a/archiva-core/src/main/java/org/apache/maven/archiva/proxy/ProxiedRepositoryGroup.java b/archiva-core/src/main/java/org/apache/maven/archiva/proxy/ProxiedRepositoryGroup.java deleted file mode 100644 index e99f09c25..000000000 --- a/archiva-core/src/main/java/org/apache/maven/archiva/proxy/ProxiedRepositoryGroup.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.apache.maven.archiva.proxy; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.wagon.proxy.ProxyInfo; - -import java.util.List; - -/** - * A set of information to store for a group of proxies. - * - * @author Brett Porter - */ -public class ProxiedRepositoryGroup -{ - - /** - * The locally managed repository that caches proxied artifacts. - */ - private ArtifactRepository managedRepository; - - /** - * The remote repositories that are being proxied. - */ - private List/**/ proxiedRepositories; - - /** - * A wagon proxy to communicate to the proxy repository over a proxy (eg, http proxy)... TerminologyOverflowException - */ - private final ProxyInfo wagonProxy; - - /** - * Constructor. - * - * @param proxiedRepositories the proxied repository - * @param managedRepository the locally managed repository - * @param wagonProxy the network proxy to use - */ - public ProxiedRepositoryGroup( List/**/ proxiedRepositories, - ArtifactRepository managedRepository, ProxyInfo wagonProxy ) - { - this.proxiedRepositories = proxiedRepositories; - - this.managedRepository = managedRepository; - - this.wagonProxy = wagonProxy; - } - - /** - * Constructor. - * - * @param proxiedRepositories the proxied repository - * @param managedRepository the locally managed repository - */ - public ProxiedRepositoryGroup( List/**/ proxiedRepositories, - ArtifactRepository managedRepository ) - { - this( proxiedRepositories, managedRepository, null ); - } - - public ArtifactRepository getManagedRepository() - { - return managedRepository; - } - - public List getProxiedRepositories() - { - return proxiedRepositories; - } - - public ProxyInfo getWagonProxy() - { - return wagonProxy; - } -} diff --git a/archiva-core/src/main/java/org/apache/maven/archiva/proxy/ProxyManager.java b/archiva-core/src/main/java/org/apache/maven/archiva/proxy/ProxyManager.java deleted file mode 100644 index 03b3a2032..000000000 --- a/archiva-core/src/main/java/org/apache/maven/archiva/proxy/ProxyManager.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.apache.maven.archiva.proxy; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.apache.maven.wagon.ResourceDoesNotExistException; - -import java.io.File; - -/** - * Repository proxying component. This component will take requests for a given path within a managed repository - * and if it is not found or expired, will look in the specified proxy repositories. - * - * @author Brett Porter - */ -public interface ProxyManager -{ - /** - * The Plexus role for the component. - */ - String ROLE = ProxyManager.class.getName(); - - /** - * Used to retrieve a cached path or retrieve one if the cache does not contain it yet. - * - * @param path the expected repository path - * @return File object referencing the requested path in the cache - * @throws ProxyException when an exception occurred during the retrieval of the requested path - * @throws org.apache.maven.wagon.ResourceDoesNotExistException - * when the requested object can't be found in any of the - * configured repositories - */ - File get( String path ) - throws ProxyException, ResourceDoesNotExistException; - - /** - * Used to force remote download of the requested path from any the configured repositories. This method will - * only bypass the cache for searching but the requested path will still be cached. - * - * @param path the expected repository path - * @return File object referencing the requested path in the cache - * @throws ProxyException when an exception occurred during the retrieval of the requested path - * @throws ResourceDoesNotExistException when the requested object can't be found in any of the - * configured repositories - */ - File getAlways( String path ) - throws ProxyException, ResourceDoesNotExistException; -} diff --git a/archiva-plexus-application/pom.xml b/archiva-plexus-application/pom.xml index c60908456..f2ece4426 100644 --- a/archiva-plexus-application/pom.xml +++ b/archiva-plexus-application/pom.xml @@ -34,7 +34,7 @@ org.codehaus.plexus plexus-appserver-maven-plugin - 2.0-alpha-5 + 2.0-alpha-7-SNAPSHOT true src/conf/application.xml diff --git a/archiva-plexus-application/src/conf/application.xml b/archiva-plexus-application/src/conf/application.xml index 53ec45b0b..37fcd4e36 100644 --- a/archiva-plexus-application/src/conf/application.xml +++ b/archiva-plexus-application/src/conf/application.xml @@ -27,7 +27,7 @@ ${plexus.home}/lib/archiva-webapp-@archivaVersion@.war - / + /archiva ${plexus.home}/webapp true diff --git a/archiva-plexus-runtime/pom.xml b/archiva-plexus-runtime/pom.xml index 8d03013e7..05f8cc5c5 100644 --- a/archiva-plexus-runtime/pom.xml +++ b/archiva-plexus-runtime/pom.xml @@ -40,13 +40,13 @@ org.codehaus.plexus plexus-appserver-host - 2.0-alpha-5 + 2.0-alpha-7-SNAPSHOT org.codehaus.plexus plexus-appserver-service-jetty - 2.0-alpha-5 + 2.0-alpha-7-SNAPSHOT plexus-service @@ -92,7 +92,7 @@ org.codehaus.plexus plexus-appserver-maven-plugin - 2.0-alpha-5 + 2.0-alpha-7-SNAPSHOT true diff --git a/archiva-security/pom.xml b/archiva-security/pom.xml index f2bc4443e..78cbd1282 100644 --- a/archiva-security/pom.xml +++ b/archiva-security/pom.xml @@ -37,5 +37,9 @@ org.codehaus.plexus.security plexus-security-system + + org.codehaus.plexus + plexus-component-api + diff --git a/archiva-webapp/pom.xml b/archiva-webapp/pom.xml index 13d1033d5..d37d0aa77 100644 --- a/archiva-webapp/pom.xml +++ b/archiva-webapp/pom.xml @@ -33,7 +33,13 @@ javax.servlet servlet-api - 2.4 + 2.5 + provided + + + javax.servlet + jsp-api + 2.0 provided @@ -140,6 +146,17 @@ org.codehaus.plexus.security plexus-security-ui-web-taglib + + + org.codehaus.plexus.webdav + plexus-webdav-simple + 1.0-alpha-1-SNAPSHOT + + + org.codehaus.plexus + plexus-xwork-integration + 1.0-alpha-5-SNAPSHOT + org.codehaus.plexus plexus-utils @@ -149,11 +166,6 @@ derby 10.1.3.1 - - it.could - webdav - 0.4 - @@ -221,7 +233,7 @@ org.mortbay.jetty maven-jetty-plugin - 6.1.0 + 6.1.1 10 / @@ -241,6 +253,10 @@ derby.system.home ${project.build.directory}/appserver-base/logs + + configuration.store.file + archiva-configuration.xml + diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/ProxyAction.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/ProxyAction.java deleted file mode 100644 index f00fae982..000000000 --- a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/ProxyAction.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.apache.maven.archiva.web.action; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import com.opensymphony.webwork.interceptor.ServletResponseAware; -import org.apache.maven.archiva.proxy.ProxyException; -import org.apache.maven.archiva.proxy.ProxyManager; -import org.apache.maven.wagon.ResourceDoesNotExistException; -import org.codehaus.plexus.xwork.action.PlexusActionSupport; - -import javax.servlet.http.HttpServletResponse; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -/** - * Proxy functionality. - * - * @plexus.component role="com.opensymphony.xwork.Action" role-hint="proxyAction" - */ -public class ProxyAction - extends PlexusActionSupport - implements ServletResponseAware -{ - /** - * @plexus.requirement - */ - private ProxyManager proxyManager; - - private String path; - - private String filename; - - private String contentType; - - private static final String NOT_FOUND = "notFound"; - - private InputStream artifactStream; - - private long contentLength; - - private HttpServletResponse httpServletResponse; - - public String execute() - throws ProxyException - { - try - { - File file = proxyManager.get( path ); - - artifactStream = new FileInputStream( file ); - - // TODO: set the correct content type and other headers! - contentType = "application/octet-stream"; - - filename = file.getName(); - - contentLength = file.length(); - - httpServletResponse.addDateHeader( "Last-Modified", file.lastModified() ); - } - catch ( ResourceDoesNotExistException e ) - { - getLogger().debug( "Requested proxy path not found: " + e.getMessage() ); - // TODO: set message? - return NOT_FOUND; - } - catch ( FileNotFoundException e ) - { - getLogger().debug( "Requested proxy file not found: " + e.getMessage() ); - // TODO: set message? - return NOT_FOUND; - } - - return SUCCESS; - } - - public String getPath() - { - return path; - } - - public void setPath( String path ) - { - this.path = path; - } - - public String getFilename() - { - return filename; - } - - public String getContentType() - { - return contentType; - } - - public long getContentLength() - { - return contentLength; - } - - public InputStream getArtifactStream() - { - return artifactStream; - } - - public void setServletResponse( HttpServletResponse httpServletResponse ) - { - this.httpServletResponse = httpServletResponse; - } -} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/AuditLog.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/AuditLog.java new file mode 100644 index 000000000..93568a2ae --- /dev/null +++ b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/AuditLog.java @@ -0,0 +1,137 @@ +package org.apache.maven.archiva.web.repository; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.commons.lang.StringUtils; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException; +import org.codehaus.plexus.webdav.DavServerComponent; +import org.codehaus.plexus.webdav.DavServerListener; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * AuditLog - Audit Log. + * + * @author Joakim Erdfelt + * @version $Id$ + * + * @plexus.component role="org.apache.maven.archiva.web.repository.AuditLog" + */ +public class AuditLog + implements DavServerListener, Initializable +{ + public static final String ROLE = AuditLog.class.getName(); + + /** + * @plexus.configuration default-value="${appserver.base}/logs/audit.log" + */ + private File logFile; + + /** + * @plexus.configuration default-value="yyyy-MM-dd HH:mm:ss" + */ + private String timestampFormat; + + private PrintWriter writer; + + private SimpleDateFormat timestamp; + + private String getServerId( DavServerComponent server ) + { + return "[" + server.getPrefix() + "]"; + } + + public void serverCollectionCreated( DavServerComponent server, String resource ) + { + log( getServerId( server ) + " Created Directory \"" + resource + "\"" ); + } + + public void serverCollectionRemoved( DavServerComponent server, String resource ) + { + log( getServerId( server ) + " Removed Directory \"" + resource + "\"" ); + } + + public void serverResourceCreated( DavServerComponent server, String resource ) + { + log( getServerId( server ) + " Created File \"" + resource + "\"" ); + } + + public void serverResourceModified( DavServerComponent server, String resource ) + { + log( getServerId( server ) + " Modified Existing File \"" + resource + "\"" ); + } + + public void serverResourceRemoved( DavServerComponent server, String resource ) + { + log( getServerId( server ) + " Removed File \"" + resource + "\"" ); + } + + /** + * Log the message to the file. + * + * @param msg the message. + */ + public void log( String msg ) + { + // Synchronize to prevent threading issues. + synchronized ( writer ) + { + writer.println( timestamp.format( new Date() ) + " - " + msg ); + // Manually flush buffer to ensure data is written to disk. + writer.flush(); + } + } + + public void initialize() + throws InitializationException + { + File parentDir = logFile.getParentFile(); + if ( parentDir != null ) + { + if ( !parentDir.exists() ) + { + parentDir.mkdirs(); + } + } + + if ( StringUtils.isBlank( timestampFormat ) ) + { + timestampFormat = "yyyy-MM-dd HH:mm:ss"; + } + + timestamp = new SimpleDateFormat( timestampFormat ); + + try + { + writer = new PrintWriter( new FileWriter( logFile ) ); + log( "Logging Initialized." ); + } + catch ( IOException e ) + { + throw new InitializationException( "Unable to initialize log file writer: " + logFile.getAbsolutePath(), e ); + } + } +} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java new file mode 100644 index 000000000..9fda5da30 --- /dev/null +++ b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java @@ -0,0 +1,198 @@ +package org.apache.maven.archiva.web.repository; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.commons.lang.StringUtils; +import org.apache.maven.archiva.configuration.Configuration; +import org.apache.maven.archiva.configuration.ConfigurationStore; +import org.apache.maven.archiva.configuration.ConfigurationStoreException; +import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory; +import org.apache.maven.archiva.configuration.ProxiedRepositoryConfiguration; +import org.apache.maven.archiva.configuration.Proxy; +import org.apache.maven.archiva.configuration.RepositoryConfiguration; +import org.apache.maven.archiva.proxy.ProxyException; +import org.apache.maven.archiva.proxy.ProxyRequestHandler; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.wagon.ResourceDoesNotExistException; +import org.apache.maven.wagon.proxy.ProxyInfo; +import org.codehaus.plexus.webdav.AbstractDavServerComponent; +import org.codehaus.plexus.webdav.DavServerComponent; +import org.codehaus.plexus.webdav.DavServerException; +import org.codehaus.plexus.webdav.servlet.DavServerRequest; +import org.codehaus.plexus.webdav.util.WebdavMethodUtil; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; + +/** + * ProxiedDavServer + * + * @author Joakim Erdfelt + * @version $Id$ + * + * @plexus.component role="org.codehaus.plexus.webdav.DavServerComponent" + * role-hint="proxied" + * instantiation-strategy="per-lookup" + */ +public class ProxiedDavServer + extends AbstractDavServerComponent +{ + /** + * @plexus.requirement role-hint="simple" + */ + private DavServerComponent davServer; + + /** + * @plexus.requirement + */ + private ConfigurationStore configurationStore; + + /** + * @plexus.requirement role="org.apache.maven.archiva.proxy.ProxyRequestHandler" + * @todo seems to be a bug in qdox that the role above is required + */ + private ProxyRequestHandler proxyRequestHandler; + + /** + * @plexus.requirement + */ + private ConfiguredRepositoryFactory repositoryFactory; + + private RepositoryConfiguration repositoryConfiguration; + + private ArtifactRepository managedRepository; + + private List/**/ proxiedRepositories; + + private ProxyInfo wagonProxy; + + public String getPrefix() + { + return davServer.getPrefix(); + } + + public File getRootDirectory() + { + return davServer.getRootDirectory(); + } + + public void setPrefix( String prefix ) + { + davServer.setPrefix( prefix ); + } + + public void setRootDirectory( File rootDirectory ) + { + davServer.setRootDirectory( rootDirectory ); + } + + public void init( ServletConfig servletConfig ) + throws DavServerException + { + davServer.init( servletConfig ); + + proxiedRepositories = new ArrayList(); + + try + { + Configuration config = configurationStore.getConfigurationFromStore(); + + wagonProxy = createWagonProxy( config.getProxy() ); + + repositoryConfiguration = config.getRepositoryByUrlName( getPrefix() ); + + managedRepository = repositoryFactory.createRepository( repositoryConfiguration ); + + for ( Iterator i = config.getProxiedRepositories().iterator(); i.hasNext(); ) + { + ProxiedRepositoryConfiguration proxiedRepoConfig = (ProxiedRepositoryConfiguration) i.next(); + + if ( proxiedRepoConfig.getManagedRepository().equals( repositoryConfiguration.getId() ) ) + { + proxiedRepositories.add( repositoryFactory.createProxiedRepository( proxiedRepoConfig ) ); + } + } + } + catch ( ConfigurationStoreException e ) + { + throw new DavServerException( "Unable to obtain configuration.", e ); + } + } + + public void process( DavServerRequest request, HttpServletResponse response ) + throws DavServerException, ServletException, IOException + { + if ( WebdavMethodUtil.isReadMethod( request.getRequest().getMethod() ) ) + { + if ( !hasResource( request.getLogicalResource() ) ) + { + fetchContentFromProxies( request ); + } + } + + davServer.process( request, response ); + } + + private void fetchContentFromProxies( DavServerRequest request ) + throws ServletException + { + try + { + proxyRequestHandler.get( request.getLogicalResource(), this.proxiedRepositories, this.managedRepository, + this.wagonProxy ); + } + catch ( ResourceDoesNotExistException e ) + { + throw new ServletException( "Unable to fetch resource, it does not exist.", e ); + } + catch ( ProxyException e ) + { + throw new ServletException( "Unable to fetch resource.", e ); + } + } + + private ProxyInfo createWagonProxy( Proxy proxy ) + { + ProxyInfo proxyInfo = null; + if ( proxy != null && StringUtils.isNotEmpty( proxy.getHost() ) ) + { + proxyInfo = new ProxyInfo(); + proxyInfo.setHost( proxy.getHost() ); + proxyInfo.setPort( proxy.getPort() ); + proxyInfo.setUserName( proxy.getUsername() ); + proxyInfo.setPassword( proxy.getPassword() ); + proxyInfo.setNonProxyHosts( proxy.getNonProxyHosts() ); + proxyInfo.setType( proxy.getProtocol() ); + } + return proxyInfo; + } + + public RepositoryConfiguration getRepositoryConfiguration() + { + return repositoryConfiguration; + } +} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java new file mode 100644 index 000000000..3f3010f91 --- /dev/null +++ b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java @@ -0,0 +1,234 @@ +package org.apache.maven.archiva.web.repository; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.archiva.configuration.Configuration; +import org.apache.maven.archiva.configuration.ConfigurationChangeException; +import org.apache.maven.archiva.configuration.ConfigurationChangeListener; +import org.apache.maven.archiva.configuration.ConfigurationStore; +import org.apache.maven.archiva.configuration.ConfigurationStoreException; +import org.apache.maven.archiva.configuration.InvalidConfigurationException; +import org.apache.maven.archiva.configuration.RepositoryConfiguration; +import org.apache.maven.archiva.security.ArchivaRoleConstants; +import org.codehaus.plexus.security.authentication.AuthenticationException; +import org.codehaus.plexus.security.authentication.AuthenticationResult; +import org.codehaus.plexus.security.authorization.AuthorizationException; +import org.codehaus.plexus.security.authorization.AuthorizationResult; +import org.codehaus.plexus.security.policy.AccountLockedException; +import org.codehaus.plexus.security.policy.MustChangePasswordException; +import org.codehaus.plexus.security.system.SecuritySession; +import org.codehaus.plexus.security.system.SecuritySystem; +import org.codehaus.plexus.security.ui.web.filter.authentication.HttpAuthenticator; +import org.codehaus.plexus.webdav.DavServerComponent; +import org.codehaus.plexus.webdav.DavServerException; +import org.codehaus.plexus.webdav.servlet.DavServerRequest; +import org.codehaus.plexus.webdav.servlet.multiplexed.MultiplexedWebDavServlet; +import org.codehaus.plexus.webdav.util.WebdavMethodUtil; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * RepositoryServlet + * + * @author Joakim Erdfelt + * @version $Id$ + */ +public class RepositoryServlet + extends MultiplexedWebDavServlet + implements ConfigurationChangeListener +{ + /** + * @plexus.requirement + */ + private SecuritySystem securitySystem; + + /** + * @plexus.requirement role-hint="basic" + */ + private HttpAuthenticator httpAuth; + + /** + * @plexus.requirement + */ + private AuditLog audit; + + private Configuration config; + + public void initComponents() + throws ServletException + { + super.initComponents(); + + ConfigurationStore configurationStore; + + configurationStore = (ConfigurationStore) lookup( ConfigurationStore.ROLE ); + securitySystem = (SecuritySystem) lookup( SecuritySystem.ROLE ); + httpAuth = (HttpAuthenticator) lookup( HttpAuthenticator.ROLE, "basic" ); + audit = (AuditLog) lookup( AuditLog.ROLE ); + + try + { + config = configurationStore.getConfigurationFromStore(); + configurationStore.addChangeListener( this ); + } + catch ( ConfigurationStoreException e ) + { + throw new ServletException( "Unable to obtain configuration.", e ); + } + + } + + public void initServers( ServletConfig servletConfig ) + throws DavServerException + { + List repositories = config.getRepositories(); + Iterator itrepos = repositories.iterator(); + while ( itrepos.hasNext() ) + { + RepositoryConfiguration repoConfig = (RepositoryConfiguration) itrepos.next(); + DavServerComponent server = createServer( repoConfig.getUrlName(), new File( repoConfig.getDirectory() ), + servletConfig ); + server.addListener( audit ); + } + } + + public RepositoryConfiguration getRepositoryConfiguration( DavServerRequest request ) + { + return config.getRepositoryByUrlName( request.getPrefix() ); + } + + public String getRepositoryName( DavServerRequest request ) + { + RepositoryConfiguration repoConfig = getRepositoryConfiguration( request ); + if ( repoConfig == null ) + { + return "Unknown"; + } + + return repoConfig.getName(); + } + + public boolean isAuthenticated( DavServerRequest davRequest, HttpServletResponse response ) + throws ServletException, IOException + { + HttpServletRequest request = davRequest.getRequest(); + + // Authentication Tests. + try + { + AuthenticationResult result = httpAuth.getAuthenticationResult( request, response ); + + if ( ( result != null ) && !result.isAuthenticated() ) + { + // Must Authenticate. + httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ), + new AuthenticationException( "User Credentials Invalid" ) ); + return false; + } + + } + catch ( AuthenticationException e ) + { + log( "Fatal Http Authentication Error.", e ); + throw new ServletException( "Fatal Http Authentication Error.", e ); + } + catch ( AccountLockedException e ) + { + httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ), + new AuthenticationException( "User account is locked" ) ); + } + catch ( MustChangePasswordException e ) + { + httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ), + new AuthenticationException( "You must change your password." ) ); + } + + return true; + } + + public boolean isAuthorized( DavServerRequest davRequest, HttpServletResponse response ) + throws ServletException, IOException + { + // Authorization Tests. + HttpServletRequest request = davRequest.getRequest(); + + boolean isWriteRequest = WebdavMethodUtil.isWriteMethod( request.getMethod() ); + + SecuritySession securitySession = httpAuth.getSecuritySession(); + try + { + String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS; + + if ( isWriteRequest ) + { + permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD; + } + + AuthorizationResult authzResult = securitySystem.authorize( securitySession, permission, + getRepositoryConfiguration( davRequest ) + .getId() ); + + if ( !authzResult.isAuthorized() ) + { + if ( authzResult.getException() != null ) + { + log( "Authorization Denied [ip=" + request.getRemoteAddr() + ",isWriteRequest=" + isWriteRequest + + ",permission=" + permission + "] : " + authzResult.getException().getMessage() ); + } + + // Issue HTTP Challenge. + httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ), + new AuthenticationException( "Authorization Denied." ) ); + return false; + } + } + catch ( AuthorizationException e ) + { + throw new ServletException( "Fatal Authorization Subsystem Error." ); + } + + return true; + } + + public void notifyOfConfigurationChange( Configuration newConfiguration ) + throws InvalidConfigurationException, ConfigurationChangeException + { + config = newConfiguration; + + getDavManager().removeAllServers(); + + try + { + initServers( getServletConfig() ); + } + catch ( DavServerException e ) + { + throw new ConfigurationChangeException( "Unable to process configuration change.", e ); + } + } +} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/AbstractPlexusServlet.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/AbstractPlexusServlet.java deleted file mode 100644 index e483674d2..000000000 --- a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/AbstractPlexusServlet.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.apache.maven.archiva.web.servlet; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.codehaus.plexus.logging.AbstractLogEnabled; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - -/** - * AbstractPlexusServlet - * - * @author Joakim Erdfelt - * @version $Id$ - */ -public abstract class AbstractPlexusServlet - extends AbstractLogEnabled - implements PlexusServlet -{ - private ServletConfig servletConfig; - - private ServletContext servletContext; - - public ServletConfig getServletConfig() - { - return servletConfig; - } - - public ServletContext getServletContext() - { - return servletContext; - } - - public void servletDestroy() - { - // Do Nothing Here. - } - - public void setServletConfig( ServletConfig config ) - throws ServletException - { - servletConfig = config; - } - - public void setServletContext( ServletContext servletContext ) - { - this.servletContext = servletContext; - } -} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/PlexusComponentServlet.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/PlexusComponentServlet.java deleted file mode 100644 index 609c200a5..000000000 --- a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/PlexusComponentServlet.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.apache.maven.archiva.web.servlet; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.codehaus.plexus.PlexusContainer; -import org.codehaus.plexus.component.repository.exception.ComponentLookupException; -import org.codehaus.plexus.xwork.PlexusLifecycleListener; - -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * PlexusComponentServlet - This is merely a servlet facade against a loaded - * plexus component called foo - * - * @author Joakim Erdfelt - * @version $Id$ - */ -public class PlexusComponentServlet - implements Servlet -{ - private PlexusContainer plexus; - - private PlexusServlet servletProxy; - - private boolean isInitialized = false; - - public void destroy() - { - if ( isInitialized ) - { - servletProxy.servletDestroy(); - } - } - - public ServletConfig getServletConfig() - { - if ( isInitialized ) - { - return servletProxy.getServletConfig(); - } - - return null; - } - - public String getServletInfo() - { - if ( isInitialized ) - { - return servletProxy.getServletInfo(); - } - - return null; - } - - public void init( ServletConfig config ) - throws ServletException - { - isInitialized = false; - - plexus = (PlexusContainer) config.getServletContext().getAttribute( PlexusLifecycleListener.KEY ); - - String componentKey = config.getInitParameter( "key" ); - - try - { - Object obj = plexus.lookup( PlexusServlet.ROLE, componentKey ); - if ( !( obj instanceof PlexusServlet ) ) - { - throw new ServletException( - "Class " + obj.getClass().getName() + " does not implement " + PlexusServlet.class.getName() ); - } - - servletProxy = (PlexusServlet) obj; - servletProxy.setServletConfig( config ); - - isInitialized = true; - } - catch ( ComponentLookupException e ) - { - throw new ServletException( "Unable to initialize PlexusComponentServlet.", e ); - } - } - - public void service( ServletRequest req, ServletResponse res ) - throws ServletException, IOException - { - if ( !isInitialized ) - { - throw new ServletException( "PlexusComponentServlet is not initialized correctly!" ); - } - - if ( !( req instanceof HttpServletRequest ) ) - { - throw new ServletException( "PlexusComponentServlet can only handle HttpServletRequests." ); - } - - if ( !( res instanceof HttpServletResponse ) ) - { - throw new ServletException( "PlexusComponentServlet can only handle HttpServletResponse." ); - } - - HttpServletRequest request = (HttpServletRequest) req; - HttpServletResponse response = (HttpServletResponse) res; - - servletProxy.servletRequest( request, response ); - } -} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/PlexusServlet.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/PlexusServlet.java deleted file mode 100644 index 4a1c7e186..000000000 --- a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/PlexusServlet.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.apache.maven.archiva.web.servlet; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * PlexusServlet - a component that handles HTTP Servlet Requests for {@link PlexusComponentServlet}. - * - * @author Joakim Erdfelt - * @version $Id$ - */ -public interface PlexusServlet -{ - public static final String ROLE = PlexusServlet.class.getName(); - - public void servletDestroy(); - - public ServletConfig getServletConfig(); - - public String getServletInfo(); - - public void setServletConfig( ServletConfig config ) - throws ServletException; - - public void servletRequest( HttpServletRequest request, HttpServletResponse response ) - throws ServletException, IOException; -} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryAccess.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryAccess.java deleted file mode 100644 index afe7a04fc..000000000 --- a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryAccess.java +++ /dev/null @@ -1,303 +0,0 @@ -package org.apache.maven.archiva.web.servlet.repository; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import it.could.webdav.DAVTransaction; -import it.could.webdav.DAVUtilities; -import org.apache.commons.lang.StringUtils; -import org.apache.maven.archiva.configuration.Configuration; -import org.apache.maven.archiva.configuration.ConfigurationStore; -import org.apache.maven.archiva.configuration.ConfigurationStoreException; -import org.apache.maven.archiva.configuration.RepositoryConfiguration; -import org.apache.maven.archiva.security.ArchivaRoleConstants; -import org.apache.maven.archiva.web.servlet.AbstractPlexusServlet; -import org.codehaus.plexus.security.authentication.AuthenticationException; -import org.codehaus.plexus.security.authentication.AuthenticationResult; -import org.codehaus.plexus.security.authorization.AuthorizationException; -import org.codehaus.plexus.security.authorization.AuthorizationResult; -import org.codehaus.plexus.security.policy.AccountLockedException; -import org.codehaus.plexus.security.policy.MustChangePasswordException; -import org.codehaus.plexus.security.system.SecuritySession; -import org.codehaus.plexus.security.system.SecuritySystem; -import org.codehaus.plexus.security.ui.web.filter.authentication.HttpAuthenticator; -import org.codehaus.plexus.util.FileUtils; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * RepositoryAccess - access read/write to the repository. - * - * @author Joakim Erdfelt - * @version $Id$ - * @plexus.component role="org.apache.maven.archiva.web.servlet.PlexusServlet" - * role-hint="repositoryAccess" - * @todo CACHE REPOSITORY LIST - */ -public class RepositoryAccess - extends AbstractPlexusServlet -{ - /** - * @plexus.requirement - */ - private ConfigurationStore configurationStore; - - /** - * @plexus.requirement - */ - private SecuritySystem securitySystem; - - /** - * @plexus.requirement role-hint="basic" - */ - private HttpAuthenticator httpAuth; - - /** - * List of request methods that fall into the category of 'access' or 'read' of a repository. - * All other method requests are to be considered 'write' or 'upload' requests. - */ - private static final List ACCESS_METHODS; - - static - { - ACCESS_METHODS = new ArrayList(); - ACCESS_METHODS.add( "HEAD" ); - ACCESS_METHODS.add( "GET" ); - ACCESS_METHODS.add( "PROPFIND" ); - ACCESS_METHODS.add( "OPTIONS" ); - ACCESS_METHODS.add( "REPORT" ); - } - - public class RequestPath - { - String repoName; - - String path; - } - - private Map davRepositoryMap = new HashMap(); - - public String getServletInfo() - { - // TODO: We could produce information about # of repositories being tracked, etc... - return "Archiva Repository Access Servlet"; - } - - public void servletRequest( HttpServletRequest request, HttpServletResponse response ) - throws ServletException, IOException - { - Configuration config; - try - { - config = configurationStore.getConfigurationFromStore(); - } - catch ( ConfigurationStoreException e ) - { - // TODO: should be a more pretty error to user. ;-) - // TODO: can we determine if the incoming request is a real user, or just maven-wagon? - - throw new ServletException( "Unable to obtain configuration.", e ); - } - - RequestPath reqpath = getRepositoryPath( request.getPathInfo() ); - - if ( reqpath == null ) - { - routeToErrorPage( response, "Invalid Repository URL." ); - return; - } - - RepositoryConfiguration repoconfig = config.getRepositoryByUrlName( reqpath.repoName ); - - if ( repoconfig == null ) - { - routeToErrorPage( response, "Invalid Repository URL." ); - return; - } - - // Authentication Tests. - try - { - AuthenticationResult result = httpAuth.getAuthenticationResult( request, response ); - - if ( ( result != null ) && !result.isAuthenticated() ) - { - // Must Authenticate. - httpAuth.challenge( request, response, "Repository " + repoconfig.getName(), - new AuthenticationException( "User Credentials Invalid" ) ); - return; - } - - } - catch ( AuthenticationException e ) - { - getLogger().error( "Fatal Http Authentication Error.", e ); - throw new ServletException( "Fatal Http Authentication Error.", e ); - } - catch ( AccountLockedException e ) - { - httpAuth.challenge( request, response, "Repository " + repoconfig.getName(), - new AuthenticationException( "User account is locked" ) ); - } - catch ( MustChangePasswordException e ) - { - httpAuth.challenge( request, response, "Repository " + repoconfig.getName(), new AuthenticationException( - "You must change your password before you can attempt this again." ) ); - } - - // Authorization Tests. - - boolean isWriteRequest = !ACCESS_METHODS.contains( request.getMethod().toUpperCase() ); - - SecuritySession securitySession = httpAuth.getSecuritySession(); - try - { - String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS; - - if ( isWriteRequest ) - { - permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD; - } - - AuthorizationResult authzResult = securitySystem - .authorize( securitySession, permission, repoconfig.getId() ); - - if ( !authzResult.isAuthorized() ) - { - if ( authzResult.getException() != null ) - { - getLogger().warn( "Authorization Denied [ip=" + request.getRemoteAddr() + ",isWriteRequest=" + - isWriteRequest + ",permission=" + permission + "] : " + - authzResult.getException().getMessage() ); - } - - // Issue HTTP Challenge. - httpAuth.challenge( request, response, "Repository " + repoconfig.getName(), - new AuthenticationException( "Authorization Denied." ) ); - return; - } - } - catch ( AuthorizationException e ) - { - throw new ServletException( "Fatal Authorization Subsystem Error." ); - } - - // Allow DAV To Handle Request. - - RepositoryMapping repo = getRepositoryMapping( repoconfig ); - - String serverInfo = ""; - if ( getServletContext() != null ) - { - if ( StringUtils.isNotEmpty( getServletContext().getServerInfo() ) ) - { - serverInfo = getServletContext().getServerInfo(); - } - } - - response.setHeader( "Server", serverInfo + " Archiva : " + DAVUtilities.SERVLET_SIGNATURE ); - - DAVTransaction transaction = - new DAVTransaction( new RepositoryRequest( request, repoconfig.getUrlName() ), response ); - try - { - repo.getDavProcessor().process( transaction ); - } - catch ( RuntimeException exception ) - { - final String header = request.getMethod() + ' ' + request.getRequestURI() + ' ' + request.getProtocol(); - getLogger().error( "Error processing: " + header ); - getLogger().error( "Exception processing DAV transaction", exception ); - throw exception; - } - } - - public RepositoryMapping getRepositoryMapping( RepositoryConfiguration repoconfig ) - throws IOException - { - RepositoryMapping repo = (RepositoryMapping) davRepositoryMap.get( repoconfig.getDirectory() ); - if ( repo == null ) - { - repo = new RepositoryMapping( repoconfig ); - davRepositoryMap.put( repoconfig.getDirectory(), repo ); - } - return repo; - } - - public RequestPath getRepositoryPath( String requestPathInfo ) - { - if ( StringUtils.isEmpty( requestPathInfo ) || StringUtils.equals( "/", requestPathInfo ) ) - { - // Got root url. Can't do anything with this. - return null; - } - - RequestPath ret = new RequestPath(); - - // Find the first 'path' of the pathInfo. - - // Default: "/pathid" -> "pathid" - ret.repoName = requestPathInfo.substring( 1 ); - ret.path = "/"; - - // Find first element, if slash exists. - int slash = requestPathInfo.indexOf( '/', 1 ); - if ( slash > 0 ) - { - // Filtered: "/central/org/apache/maven/" -> "central" - ret.repoName = requestPathInfo.substring( 1, slash ); - - String repoPath = requestPathInfo.substring( slash ); - - if ( repoPath.endsWith( "/.." ) ) - { - repoPath += "/"; - } - - String path = FileUtils.normalize( repoPath ); - if ( path == null ) - { - ret.path = "/"; - } - else - { - ret.path = path; - } - } - - return ret; - } - - public void routeToErrorPage( HttpServletResponse response, String message ) - throws IOException - { - response.resetBuffer(); - /* Since the primary user of this servlet will be Maven Wagon. - * Always return 404 on error to force the wagon to stop retrying. - */ - response.sendError( HttpServletResponse.SC_NOT_FOUND, message ); - } -} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryException.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryException.java deleted file mode 100644 index 891d3f6cb..000000000 --- a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryException.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.apache.maven.archiva.web.servlet.repository; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * RepositoryException - * - * @author Joakim Erdfelt - * @version $Id$ - */ -public class RepositoryException - extends Exception -{ - - public RepositoryException() - { - super(); - } - - public RepositoryException( String message, Throwable cause ) - { - super( message, cause ); - } - - public RepositoryException( String message ) - { - super( message ); - } - - public RepositoryException( Throwable cause ) - { - super( cause ); - } -} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryMapping.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryMapping.java deleted file mode 100644 index a602cc77f..000000000 --- a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryMapping.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.apache.maven.archiva.web.servlet.repository; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import it.could.webdav.DAVListener; -import it.could.webdav.DAVProcessor; -import it.could.webdav.DAVRepository; -import it.could.webdav.DAVResource; -import org.apache.maven.archiva.configuration.RepositoryConfiguration; -import org.codehaus.plexus.logging.Logger; - -import java.io.File; -import java.io.IOException; - -/** - * RepositoryMapping - * - * @author Joakim Erdfelt - * @version $Id$ - */ -public class RepositoryMapping - implements DAVListener -{ - private RepositoryConfiguration repositoryConfiguration; - - private DAVProcessor davProcessor; - - private DAVRepository davRepository; - - private Logger logger; - - public RepositoryMapping( RepositoryConfiguration repoConfig ) - throws IOException - { - this.repositoryConfiguration = repoConfig; - File repoDir = new File( repositoryConfiguration.getDirectory() ); - this.davRepository = new DAVRepository( repoDir ); - this.davProcessor = new DAVProcessor( this.davRepository ); - this.davRepository.addListener( this ); - } - - public DAVProcessor getDavProcessor() - { - return davProcessor; - } - - /** - *

Receive notification of an event occurred in a specific - * {@link DAVRepository}.

- */ - public void notify( DAVResource resource, int event ) - { - String message = "Unknown event"; - switch ( event ) - { - case DAVListener.COLLECTION_CREATED: - message = "Collection created"; - break; - case DAVListener.COLLECTION_REMOVED: - message = "Collection removed"; - break; - case DAVListener.RESOURCE_CREATED: - message = "Resource created"; - break; - case DAVListener.RESOURCE_REMOVED: - message = "Resource removed"; - break; - case DAVListener.RESOURCE_MODIFIED: - message = "Resource modified"; - break; - } - logger.info( - message + ": " + this.repositoryConfiguration.getId() + " : \"" + resource.getRelativePath() + "\"" ); - } -} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryRequest.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryRequest.java deleted file mode 100644 index 1e4e25cf2..000000000 --- a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryRequest.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.apache.maven.archiva.web.servlet.repository; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import it.could.webdav.DAVTransaction; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; - -/** - * RepositoryRequest - * - * @author Joakim Erdfelt - * @version $Id$ - */ -public class RepositoryRequest - extends HttpServletRequestWrapper -{ - private String repoUrlName; - - public RepositoryRequest( HttpServletRequest request, String repoUrlName ) - { - super( request ); - this.repoUrlName = ""; - - if ( repoUrlName != null ) - { - this.repoUrlName = repoUrlName; - } - } - - /** - * Adjust the path info value to remove reference to repoUrlName. - * This is done to satisfy the needs of {@link DAVTransaction} - */ - public String getPathInfo() - { - String pathInfo = super.getPathInfo(); - - if ( pathInfo == null ) - { - return ""; - } - - if ( ( pathInfo.length() > 1 ) && ( pathInfo.charAt( 0 ) == '/' ) ) - { - pathInfo = pathInfo.substring( 1 ); - } - - if ( pathInfo.startsWith( repoUrlName ) ) - { - pathInfo = pathInfo.substring( repoUrlName.length() ); - } - - return pathInfo; - } - - public String getServletPath() - { - return super.getServletPath() + "/" + this.repoUrlName; - } - -} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/GroupIdLink.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/GroupIdLink.java new file mode 100644 index 000000000..02347c150 --- /dev/null +++ b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/GroupIdLink.java @@ -0,0 +1,148 @@ +package org.apache.maven.archiva.web.tags; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import com.opensymphony.webwork.WebWorkException; +import com.opensymphony.webwork.components.Component; +import com.opensymphony.xwork.util.OgnlValueStack; + +import java.io.IOException; +import java.io.Writer; +import java.util.StringTokenizer; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * GroupIdLink + * + * @author Joakim Erdfelt + * @version $Id$ + */ +public class GroupIdLink + extends Component +{ + private static final String ACTION = "browseGroup"; + + private static final String NAMESPACE = "/"; + + private static final boolean includeContext = false; + + private static final boolean encode = true; + + private static final String method = null; + + private HttpServletRequest req; + + private HttpServletResponse res; + + private String groupId; + + private boolean includeTop = false; + + public GroupIdLink( OgnlValueStack stack, HttpServletRequest req, HttpServletResponse res ) + { + super( stack ); + this.req = req; + this.res = res; + } + + public boolean end( Writer writer, String body ) + { + StringBuffer sb = new StringBuffer(); + + sb.append( "" ); + + if ( includeTop ) + { + sb.append( "[top] / " ); // TODO: i18n + } + + StringTokenizer tok = new StringTokenizer( groupId, "." ); + String cumulativeGroup = null; + + while ( tok.hasMoreTokens() ) + { + String token = tok.nextToken(); + + if ( cumulativeGroup == null ) + { + cumulativeGroup = token; + } + else + { + cumulativeGroup += "." + token; + } + sb.append( "" ).append( token ).append( " / " ); + } + + sb.append( "" ); + + try + { + writer.write( sb.toString() ); + } + catch ( IOException e ) + { + throw new WebWorkException( "IOError: " + e.getMessage(), e ); + } + + return super.end( writer, body ); + } + + private String determineBrowseActionUrl() + { + return determineActionURL( "browse", NAMESPACE, method, req, res, parameters, req.getScheme(), includeContext, + encode ); + } + + private String determineBrowseGroupActionUrl( String gid ) + { + parameters.put( "groupId", gid ); + + return determineActionURL( ACTION, NAMESPACE, method, req, res, parameters, req.getScheme(), includeContext, + encode ); + } + + public String getGroupId() + { + return groupId; + } + + public void setGroupId( String groupId ) + { + this.groupId = groupId; + } + + public boolean isIncludeTop() + { + return includeTop; + } + + public void setIncludeTop( boolean includeTop ) + { + this.includeTop = includeTop; + } + +} diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/GroupIdLinkTag.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/GroupIdLinkTag.java new file mode 100644 index 000000000..449fe9635 --- /dev/null +++ b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/GroupIdLinkTag.java @@ -0,0 +1,100 @@ +package org.apache.maven.archiva.web.tags; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import com.opensymphony.webwork.views.jsp.TagUtils; + +import org.apache.taglibs.standard.tag.common.core.NullAttributeException; +import org.apache.taglibs.standard.tag.el.core.ExpressionUtil; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.TagSupport; + +/** + * GroupIdLink + * + * @author Joakim Erdfelt + * @version $Id$ + */ +public class GroupIdLinkTag + extends TagSupport +{ + private String var_; // stores EL-based property + + private Object var; // stores the evaluated object. + + private boolean includeTop = false; + + public void release() + { + var_ = null; + var = null; + includeTop = false; + + super.release(); + } + + public int doEndTag() + throws JspException + { + evaluateExpressions(); + + GroupIdLink gidlink = new GroupIdLink( TagUtils.getStack( pageContext ), (HttpServletRequest) pageContext + .getRequest(), (HttpServletResponse) pageContext.getResponse() ); + + gidlink.setGroupId( var.toString() ); + gidlink.setIncludeTop( includeTop ); + + gidlink.end( pageContext.getOut(), "" ); + + return super.doEndTag(); + } + + private void evaluateExpressions() + throws JspException + { + try + { + var = ExpressionUtil.evalNotNull( "groupIdLink", "var", var_, String.class, this, pageContext ); + } + catch ( NullAttributeException e ) + { + log( "groupIdLink var is null!", e ); + var = ""; + } + } + + public void setVar( String value ) + { + this.var_ = value; + } + + private void log( String msg, Throwable t ) + { + pageContext.getServletContext().log( msg, t ); + } + + public void setIncludeTop( boolean includeTop ) + { + this.includeTop = includeTop; + } +} diff --git a/archiva-webapp/src/main/resources/META-INF/plexus/application.xml b/archiva-webapp/src/main/resources/META-INF/plexus/application.xml index 5ab5e01f5..756ef925c 100644 --- a/archiva-webapp/src/main/resources/META-INF/plexus/application.xml +++ b/archiva-webapp/src/main/resources/META-INF/plexus/application.xml @@ -40,6 +40,16 @@ java:comp/env/mail/Session
+ + + org.codehaus.plexus.webdav.DavServerManager + default + org.codehaus.plexus.webdav.DefaultDavServerManager + DefaultDavServerManager + + proxied + + org.codehaus.plexus.jdo.JdoFactory @@ -130,36 +140,9 @@ - - - audit - DEBUG - org.apache.log4j.DailyRollingFileAppender - %-4r [%t] %-5p %c %x - %m%n - - - - file - ${appserver.base}/logs/audit.log - - - append - true - - - datePattern - '.'yyyy-MM-dd - - - - - org.apache.maven.archiva.web.servlet.repository.RepositoryMapping - DEBUG, audit - - org.apache.maven diff --git a/archiva-webapp/src/main/resources/META-INF/taglib.tld b/archiva-webapp/src/main/resources/META-INF/taglib.tld new file mode 100644 index 000000000..4d38c05ee --- /dev/null +++ b/archiva-webapp/src/main/resources/META-INF/taglib.tld @@ -0,0 +1,40 @@ + + + + + + 2.2.3 + 1.2 + Archiva Taglib + + http://maven.apache.org/archiva + + Archiva Taglib + + + + + groupIdLink + org.apache.maven.archiva.web.tags.GroupIdLinkTag + empty + + + + var + true + true + + + + + + includeTop + false + true + + + + + + + \ No newline at end of file diff --git a/archiva-webapp/src/main/resources/xwork.xml b/archiva-webapp/src/main/resources/xwork.xml index 8484a94b1..96c9bdb21 100644 --- a/archiva-webapp/src/main/resources/xwork.xml +++ b/archiva-webapp/src/main/resources/xwork.xml @@ -181,16 +181,6 @@ /WEB-INF/jsp/showArtifact.jsp - - - ${contentType} - filename="${filename}" - artifactStream - 1024 - ${contentLength} - - 404 - diff --git a/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/managedRepositories.jsp b/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/managedRepositories.jsp index 0c51db9b2..d79368bc5 100644 --- a/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/managedRepositories.jsp +++ b/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/managedRepositories.jsp @@ -79,7 +79,7 @@ WebDAV URL - ${urlbase}${repository.urlName} + ${urlbase}${repository.urlName}/ Type @@ -121,7 +121,7 @@ <repository> <id>${repository.id}</id> <name>${repository.name}</name> - <url>${urlbase}${repository.urlName}</url> + <url>${urlbase}${repository.urlName}/</url> <layout>${repository.layout}</layout> <releases> <enabled>${repository.includeSnapshots ? 'false' : 'true'}</enabled> diff --git a/archiva-webapp/src/main/webapp/WEB-INF/jsp/browseArtifact.jsp b/archiva-webapp/src/main/webapp/WEB-INF/jsp/browseArtifact.jsp index de31c5373..3dde3fca8 100644 --- a/archiva-webapp/src/main/webapp/WEB-INF/jsp/browseArtifact.jsp +++ b/archiva-webapp/src/main/webapp/WEB-INF/jsp/browseArtifact.jsp @@ -19,6 +19,7 @@ <%@ taglib prefix="ww" uri="/webwork" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %> @@ -33,23 +34,7 @@

- - - - - - - - - - - - - - - - ${part} / - + ${artifactId}

diff --git a/archiva-webapp/src/main/webapp/WEB-INF/jsp/browseGroup.jsp b/archiva-webapp/src/main/webapp/WEB-INF/jsp/browseGroup.jsp index 294428e73..dd7218779 100644 --- a/archiva-webapp/src/main/webapp/WEB-INF/jsp/browseGroup.jsp +++ b/archiva-webapp/src/main/webapp/WEB-INF/jsp/browseGroup.jsp @@ -19,6 +19,7 @@ <%@ taglib prefix="ww" uri="/webwork" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %> @@ -33,30 +34,7 @@

- - - - - - - - - - - - - ${part} - - - - - - - - ${part} / - - - +

diff --git a/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/artifactInfo.jspf b/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/artifactInfo.jspf index 2e61d2d96..7a206a351 100644 --- a/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/artifactInfo.jspf +++ b/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/artifactInfo.jspf @@ -19,25 +19,11 @@ <%@ taglib prefix="ww" uri="/webwork" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>

- - - - - - - - - - - - - - - - ${part} / - + + diff --git a/archiva-webapp/src/main/webapp/WEB-INF/tags/showArtifactLink.tag b/archiva-webapp/src/main/webapp/WEB-INF/tags/showArtifactLink.tag index 0a39338d1..53676a6ab 100644 --- a/archiva-webapp/src/main/webapp/WEB-INF/tags/showArtifactLink.tag +++ b/archiva-webapp/src/main/webapp/WEB-INF/tags/showArtifactLink.tag @@ -19,6 +19,7 @@ <%@ taglib prefix="ww" uri="/webwork" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %> <%@ attribute name="groupId" required="true" %> <%@ attribute name="artifactId" %> <%@ attribute name="version" %> @@ -27,26 +28,8 @@ <%@ attribute name="versions" type="java.util.List" %> - - - - - - - - - - - - - - - - ${part} - - / - - + + diff --git a/archiva-webapp/src/main/webapp/WEB-INF/web.xml b/archiva-webapp/src/main/webapp/WEB-INF/web.xml index 7c6cb40c1..b2de4ebf3 100644 --- a/archiva-webapp/src/main/webapp/WEB-INF/web.xml +++ b/archiva-webapp/src/main/webapp/WEB-INF/web.xml @@ -60,16 +60,12 @@ - RepositoryAccessServlet - org.apache.maven.archiva.web.servlet.PlexusComponentServlet - - key - repositoryAccess - + RepositoryServlet + org.apache.maven.archiva.web.repository.RepositoryServlet - RepositoryAccessServlet + RepositoryServlet /repository/* diff --git a/archiva-webapp/src/test/java/org/apache/maven/archiva/web/servlet/repository/RepositoryAccessTest.java b/archiva-webapp/src/test/java/org/apache/maven/archiva/web/servlet/repository/RepositoryAccessTest.java deleted file mode 100644 index c893338ae..000000000 --- a/archiva-webapp/src/test/java/org/apache/maven/archiva/web/servlet/repository/RepositoryAccessTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.apache.maven.archiva.web.servlet.repository; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.apache.maven.archiva.web.servlet.PlexusServlet; -import org.codehaus.plexus.PlexusTestCase; - -/** - * RepositoryAccessTest - * - * @author Joakim Erdfelt - * @version $Id$ - */ -public class RepositoryAccessTest - extends PlexusTestCase -{ - private void assertRequestPath( String expectedId, String expectedPath, String rawpath ) - throws Exception - { - RepositoryAccess repoaccess = (RepositoryAccess) lookup( PlexusServlet.ROLE, "repositoryAccess" ); - - RepositoryAccess.RequestPath requestPath = repoaccess.getRepositoryPath( rawpath ); - - if ( expectedId == null ) - { - // special case, should be null. - assertNull( requestPath ); - return; - } - - assertNotNull( requestPath ); - - assertEquals( expectedId, requestPath.repoName ); - assertEquals( expectedPath, requestPath.path ); - } - - public void testGetRepoPath() - throws Exception - { - // Test for paths with no id. - assertRequestPath( null, null, null ); - assertRequestPath( null, null, "" ); - assertRequestPath( null, null, "/" ); - - // Test for paths with root browse - assertRequestPath( "central", "/", "/central" ); - assertRequestPath( "central", "/", "/central/" ); - assertRequestPath( "snapshots", "/", "/snapshots/" ); - - // Test for paths deep within repository. - assertRequestPath( "central", "/org/apache/maven/", "/central/org/apache/maven/" ); - assertRequestPath( "snapshots", "/org/codehaus/mojo", "/snapshots/org/codehaus/mojo" ); - - assertRequestPath( "central", "/org/apache/maven/archiva/metadata.xml", - "/central/org/apache/maven/archiva/metadata.xml" ); - assertRequestPath( "sandbox", "/org/company/experiment/1.0/experiment-1.0.jar.pom", - "/sandbox/org/company/experiment/1.0/experiment-1.0.jar.pom" ); - - // Test for paths with "/../" nastyness - assertRequestPath( "central", "/", "/central/.." ); - assertRequestPath( "central", "/", "/central/../../../" ); - assertRequestPath( "central", "/", "/central/org/../../etc/passwd" ); - assertRequestPath( "central", "/etc/passwd", "/central//etc/passwd" ); - assertRequestPath( "central", "/org/codehaus/mojo", "/central/org/apache/../codehaus/mojo" ); - } -} diff --git a/pom.xml b/pom.xml index e0adf2f97..b05785b3f 100644 --- a/pom.xml +++ b/pom.xml @@ -154,15 +154,44 @@ maven-app-configuration-web 1.0-SNAPSHOT + org.codehaus.plexus plexus-container-default - 1.0-alpha-10 + 1.0-alpha-16-SNAPSHOT + + + org.codehaus.plexus + plexus-component-api + 1.0-alpha-16-SNAPSHOT org.codehaus.plexus plexus-utils - 1.3 + 1.4 org.apache.maven @@ -188,6 +217,12 @@ org.apache.maven maven-project ${maven.version} + + + plexus + plexus-container-default + + org.apache.maven @@ -400,6 +435,7 @@ maven-javadoc-plugin + 1.4 true diff --git a/src/site/apt/guides/getting-started/index.apt b/src/site/apt/guides/getting-started/index.apt index 7666dd749..0b362515e 100644 --- a/src/site/apt/guides/getting-started/index.apt +++ b/src/site/apt/guides/getting-started/index.apt @@ -94,7 +94,7 @@ To deploy Archiva on Plexus Setting up your Archiva instance - * Goto {{http://localhost:9091/}} if on the embedded Jetty, {{http://localhost:8080/archiva/}} if on Tomcat or {{http://localhost:8080/}} if on Plexus. + * Goto {{http://localhost:9091/}} if on the embedded Jetty, {{http://localhost:8080/archiva/}} if on Tomcat or {{http://localhost:8080/archiva/}} if on Plexus. * On the first page - setup your administration user. The password requires a numerical character and must not be longer than 8 chars. You'll then need to log in. User 'admin' as the username and the password you've entered. -- 2.39.5