]> source.dussan.org Git - archiva.git/commitdiff
MRM-172 patch provided by joakim for adding webdev authenticationa nd authorization...
authorJesse McConnell <jmcconnell@apache.org>
Thu, 14 Sep 2006 01:29:27 +0000 (01:29 +0000)
committerJesse McConnell <jmcconnell@apache.org>
Thu, 14 Sep 2006 01:29:27 +0000 (01:29 +0000)
git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@443183 13f79535-47bb-0310-9956-ffa450edef68

archiva-webapp/pom.xml
archiva-webapp/src/main/java/org/apache/maven/archiva/web/ArchivaDefaults.java [new file with mode: 0644]
archiva-webapp/src/main/java/org/apache/maven/archiva/web/DefaultArchivaDefaults.java [new file with mode: 0644]
archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/AbstractPlexusServlet.java [new file with mode: 0644]
archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/PlexusComponentServlet.java [new file with mode: 0644]
archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/PlexusServlet.java [new file with mode: 0644]
archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryAccess.java [new file with mode: 0644]
archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryException.java [new file with mode: 0644]
archiva-webapp/src/main/java/org/apache/maven/archiva/web/servlet/repository/RepositoryMapping.java [new file with mode: 0644]
archiva-webapp/src/main/java/org/apache/maven/archiva/web/util/DefaultRoleManager.java
archiva-webapp/src/main/webapp/WEB-INF/web.xml

index 82d48a15b616ce9c18c41b13c424ebb06b26cc57..a36ff7e67c1150283ca697503d6b6ddebe8710b3 100644 (file)
@@ -1,3 +1,5 @@
+<?xml version="1.0" ?>
+
 <!--
   ~ Copyright 2005-2006 The Apache Software Foundation.
   ~
         </exclusion>
       </exclusions>
     </dependency>
+    <dependency>
+      <groupId>it.could</groupId>
+      <artifactId>webdav</artifactId>
+      <version>0.4</version>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/ArchivaDefaults.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/ArchivaDefaults.java
new file mode 100644 (file)
index 0000000..0fdb6be
--- /dev/null
@@ -0,0 +1,99 @@
+package org.apache.maven.archiva.web;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.security.user.User;
+
+/**
+ * ArchivaDefaults
+ *
+ * NOTE: this is targeted for removal with the forth coming rbac role templating 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface ArchivaDefaults
+{
+    public static final String ROLE = ArchivaDefaults.class.getName();
+
+    public static final String GUEST_USERNAME = "guest";
+    
+    public static final String CONFIGURATION_EDIT_OPERATION = "edit-configuration";
+    
+    public static final String CONFIGURATION_EDIT_PERMISSION = "Edit Configuration";
+    
+    public static final String INDEX_REGENERATE_OPERATION = "regenerate-index";
+
+    public static final String INDEX_REGENERATE_PERMISSION = "Regenerate Index";
+
+    public static final String INDEX_RUN_OPERATION = "run-indexer";
+
+    public static final String INDEX_RUN_PERMISSION = "Run Indexer";
+
+    public static final String REPORTS_ACCESS_OPERATION = "access-reports";
+
+    public static final String REPORTS_ACCESS_PERMISSION = "Access Reports";
+
+    public static final String REPORTS_GENERATE_OPERATION = "generate-reports";
+
+    public static final String REPORTS_GENERATE_PERMISSION = "Generate Reports";
+
+    public static final String REPOSITORY_ACCESS = "Access Repository";
+
+    public static final String REPOSITORY_ACCESS_OPERATION = "read-repository";
+
+    public static final String REPOSITORY_ADD_OPERATION = "add-repository";
+
+    public static final String REPOSITORY_ADD_PERMISSION = "Add Repository";
+
+    public static final String REPOSITORY_DELETE = "Delete Repository";
+    
+    public static final String REPOSITORY_DELETE_OPERATION = "delete-repository";
+
+    public static final String REPOSITORY_EDIT = "Edit Repository";
+    
+    public static final String REPOSITORY_EDIT_OPERATION = "edit-repository";
+    
+    public static final String REPOSITORY_MANAGER = "Repository Manager";
+    
+    public static final String REPOSITORY_OBSERVER = "Repository Observer";
+
+    public static final String REPOSITORY_UPLOAD = "Repository Upload";
+
+    public static final String REPOSITORY_UPLOAD_OPERATION = "upload-repository";
+
+    public static final String ROLES_GRANT_OPERATION = "grant-roles";
+
+    public static final String ROLES_GRANT_PERMISSION = "Grant Roles";
+
+    public static final String ROLES_REMOVE_OPERATION = "remove-roles";
+
+    public static final String ROLES_REMOVE_PERMISSION = "Remove Roles";
+
+    public static final String SYSTEM_ADMINISTRATOR = "System Administrator";
+
+    public static final String USER_ADMINISTRATOR = "User Administrator";
+
+    public static final String USER_EDIT_OPERATION = "edit-user";
+
+    public static final String USERS_EDIT_ALL_OPERATION = "edit-all-users";
+
+    public static final String USERS_EDIT_ALL_PERMISSION = "Edit All Users";
+    
+    public void ensureDefaultsExist();
+    public User getGuestUser();
+}
diff --git a/archiva-webapp/src/main/java/org/apache/maven/archiva/web/DefaultArchivaDefaults.java b/archiva-webapp/src/main/java/org/apache/maven/archiva/web/DefaultArchivaDefaults.java
new file mode 100644 (file)
index 0000000..50399df
--- /dev/null
@@ -0,0 +1,174 @@
+package org.apache.maven.archiva.web;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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 org.codehaus.plexus.security.rbac.Operation;
+import org.codehaus.plexus.security.rbac.Permission;
+import org.codehaus.plexus.security.rbac.RBACManager;
+import org.codehaus.plexus.security.rbac.RbacObjectNotFoundException;
+import org.codehaus.plexus.security.rbac.Role;
+import org.codehaus.plexus.security.user.User;
+import org.codehaus.plexus.security.user.UserManager;
+
+/**
+ * DefaultArchivaDefaults 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ * @plexus.component role="org.apache.maven.archiva.web.ArchivaDefaults"
+ */
+public class DefaultArchivaDefaults
+    extends AbstractLogEnabled
+    implements ArchivaDefaults
+{
+    /**
+     * @plexus.requirement
+     */
+    private RBACManager rbacManager;
+
+    /**
+     * @plexus.requirement
+     */
+    private UserManager userManager;
+
+    private boolean initialized;
+
+    private User guestUser;
+
+    public void ensureDefaultsExist()
+    {
+        if ( initialized )
+        {
+            return;
+        }
+
+        ensureOperationsExist();
+        ensurePermissionsExist();
+        ensureRolesExist();
+        ensureUsersExist();
+        initialized = true;
+    }
+
+    private void ensureOperationExists( String operationName )
+    {
+        if ( !rbacManager.operationExists( operationName ) )
+        {
+            Operation operation = rbacManager.createOperation( operationName );
+            rbacManager.saveOperation( operation );
+        }
+    }
+
+    private void ensureOperationsExist()
+    {
+        ensureOperationExists( REPOSITORY_ADD_OPERATION );
+        ensureOperationExists( REPOSITORY_EDIT_OPERATION );
+        ensureOperationExists( REPOSITORY_DELETE_OPERATION );
+        ensureOperationExists( CONFIGURATION_EDIT_OPERATION );
+        ensureOperationExists( INDEX_RUN_OPERATION );
+        ensureOperationExists( INDEX_REGENERATE_OPERATION );
+        ensureOperationExists( REPORTS_ACCESS_OPERATION );
+        ensureOperationExists( REPORTS_GENERATE_OPERATION );
+        ensureOperationExists( USER_EDIT_OPERATION );
+        ensureOperationExists( USERS_EDIT_ALL_OPERATION );
+        ensureOperationExists( ROLES_GRANT_OPERATION );
+        ensureOperationExists( ROLES_REMOVE_OPERATION );
+        ensureOperationExists( REPOSITORY_ACCESS_OPERATION );
+        ensureOperationExists( REPOSITORY_UPLOAD_OPERATION );
+    }
+
+    private void ensurePermissionExists( String permissionName, String operationName, String resourceIdentifier )
+    {
+        if ( !rbacManager.permissionExists( permissionName ) )
+        {
+            Permission editConfiguration = rbacManager.createPermission( permissionName, operationName,
+                                                                         resourceIdentifier );
+            rbacManager.savePermission( editConfiguration );
+        }
+    }
+
+    private void ensurePermissionsExist()
+    {
+        String globalResource = rbacManager.getGlobalResource().getIdentifier();
+
+        ensurePermissionExists( USERS_EDIT_ALL_PERMISSION, USERS_EDIT_ALL_OPERATION, globalResource );
+        
+        ensurePermissionExists( CONFIGURATION_EDIT_PERMISSION, CONFIGURATION_EDIT_OPERATION, globalResource );
+        
+        ensurePermissionExists( ROLES_GRANT_PERMISSION, ROLES_GRANT_OPERATION, globalResource );
+        ensurePermissionExists( ROLES_REMOVE_PERMISSION, ROLES_REMOVE_OPERATION, globalResource );
+        
+        ensurePermissionExists( REPORTS_ACCESS_PERMISSION, REPORTS_ACCESS_OPERATION, globalResource );
+        ensurePermissionExists( REPORTS_GENERATE_PERMISSION, REPORTS_GENERATE_OPERATION, globalResource );
+        
+        ensurePermissionExists( INDEX_RUN_PERMISSION, INDEX_RUN_OPERATION, globalResource );
+        ensurePermissionExists( INDEX_REGENERATE_PERMISSION, INDEX_REGENERATE_OPERATION, globalResource );
+        
+        ensurePermissionExists( REPOSITORY_ADD_PERMISSION, REPOSITORY_ADD_OPERATION, globalResource );
+        ensurePermissionExists( REPOSITORY_ACCESS, "access-repository", globalResource );
+        ensurePermissionExists( REPOSITORY_UPLOAD, REPOSITORY_UPLOAD_OPERATION, globalResource );
+    }
+
+    private void ensureRolesExist()
+    {
+        try
+        {
+            if ( !rbacManager.roleExists( USER_ADMINISTRATOR ) )
+            {
+                Role userAdmin = rbacManager.createRole( USER_ADMINISTRATOR );
+                userAdmin.addPermission( rbacManager.getPermission( USERS_EDIT_ALL_PERMISSION ) );
+                userAdmin.addPermission( rbacManager.getPermission( ROLES_REMOVE_PERMISSION ) );
+                userAdmin.addPermission( rbacManager.getPermission( ROLES_GRANT_PERMISSION ) );
+                userAdmin.setAssignable( true );
+                rbacManager.saveRole( userAdmin );
+            }
+
+            if ( !rbacManager.roleExists( SYSTEM_ADMINISTRATOR ) )
+            {
+                Role admin = rbacManager.createRole( SYSTEM_ADMINISTRATOR );
+                admin.addChildRoleName( rbacManager.getRole( USER_ADMINISTRATOR ).getName() );
+                admin.addPermission( rbacManager.getPermission( CONFIGURATION_EDIT_PERMISSION ) );
+                admin.addPermission( rbacManager.getPermission( INDEX_RUN_PERMISSION ) );
+                admin.addPermission( rbacManager.getPermission( REPOSITORY_ADD_PERMISSION ) );
+                admin.addPermission( rbacManager.getPermission( REPORTS_ACCESS_PERMISSION ) );
+                admin.addPermission( rbacManager.getPermission( REPORTS_GENERATE_PERMISSION ) );
+                admin.addPermission( rbacManager.getPermission( INDEX_REGENERATE_PERMISSION ) );
+                admin.setAssignable( true );
+                rbacManager.saveRole( admin );
+            }
+        }
+        catch ( RbacObjectNotFoundException ne )
+        {
+            getLogger().fatalError( "Unable to initialize Roles!", ne );
+            throw new RuntimeException( "All Mandatory Defaults do not Exist!" );
+        }
+    }
+
+    public void ensureUsersExist()
+    {
+        if ( !userManager.userExists( GUEST_USERNAME ) )
+        {
+            this.guestUser = userManager.createUser( GUEST_USERNAME, "Guest User", "" );
+            this.guestUser = userManager.addUser( this.guestUser );
+        }
+    }
+
+    public User getGuestUser()
+    {
+        return this.guestUser;
+    }
+}
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
new file mode 100644 (file)
index 0000000..c890f0c
--- /dev/null
@@ -0,0 +1,63 @@
+package org.apache.maven.archiva.web.servlet;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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 <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @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
new file mode 100644 (file)
index 0000000..138af13
--- /dev/null
@@ -0,0 +1,128 @@
+package org.apache.maven.archiva.web.servlet;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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 <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @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
new file mode 100644 (file)
index 0000000..bccb144
--- /dev/null
@@ -0,0 +1,46 @@
+package org.apache.maven.archiva.web.servlet;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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 <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @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
new file mode 100644 (file)
index 0000000..68e277d
--- /dev/null
@@ -0,0 +1,276 @@
+package org.apache.maven.archiva.web.servlet.repository;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.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.web.ArchivaDefaults;
+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.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 org.codehaus.plexus.util.StringUtils;
+
+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.
+ *
+ * @plexus.component role="org.apache.maven.archiva.web.servlet.PlexusServlet" 
+ *                   role-hint="repositoryAccess"
+ * 
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ * @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;
+
+    /**
+     * @plexus.requirement
+     */
+    private ArchivaDefaults archiva;
+
+    /**
+     * 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( "GET" );
+        ACCESS_METHODS.add( "PROPFIND" );
+        ACCESS_METHODS.add( "OPTIONS" );
+        ACCESS_METHODS.add( "REPORT" );
+    }
+
+    public class RequestPath
+    {
+        String repoId;
+
+        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. ;-)
+
+            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.getRepositoryById( reqpath.repoId );
+
+        if ( repoconfig == null )
+        {
+            routeToErrorPage( response, "Invalid Repository ID." );
+            return;
+        }
+
+        // Authentication Tests.
+
+        AuthenticationResult result;
+        try
+        {
+            result = httpAuth.getAuthenticationResult( request, response, archiva.getGuestUser().getPrincipal()
+                .toString() );
+
+            if ( !result.isAuthenticated() )
+            {
+                // Must Authenticate.
+                httpAuth.challenge( request, response, "Repository " + repoconfig.getName(), null );
+                return;
+            }
+        }
+        catch ( AuthenticationException e )
+        {
+            getLogger().error( "Fatal Http Authentication Error.", e );
+            throw new ServletException( "Fatal Http Authentication Error.", e );
+        }
+
+        // Authorization Tests.
+
+        boolean isWriteRequest = !ACCESS_METHODS.contains( request.getMethod().toUpperCase() );
+
+        SecuritySession securitySession = httpAuth.getSecuritySession();
+        try
+        {
+            String permission = ArchivaDefaults.REPOSITORY_ACCESS; 
+
+            if ( isWriteRequest )
+            {
+                permission = ArchivaDefaults.REPOSITORY_UPLOAD;
+            }
+
+            permission += " - " + repoconfig.getId();
+
+            boolean isAuthorized = securitySystem.isAuthorized( securitySession, permission, repoconfig.getId() );
+
+            if ( !isAuthorized )
+            {
+                // Issue HTTP Challenge.
+                httpAuth.challenge( request, response, "Repository " + repoconfig.getName(), null );
+                return;
+            }
+        }
+        catch ( AuthorizationException e )
+        {
+            throw new ServletException( "Fatal Authorization Subsystem Error." );
+        }
+
+        // Allow DAV To Handle Request.
+
+        RepositoryMapping repo = getRepositoryMapping( repoconfig );
+
+        response.setHeader( "Server", getServletContext().getServerInfo() + " Archiva : "
+            + DAVUtilities.SERVLET_SIGNATURE );
+
+        DAVTransaction transaction = new DAVTransaction( request, 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.repoId = 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.repoId = 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
new file mode 100644 (file)
index 0000000..5f37fe5
--- /dev/null
@@ -0,0 +1,48 @@
+package org.apache.maven.archiva.web.servlet.repository;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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 <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @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
new file mode 100644 (file)
index 0000000..057cc71
--- /dev/null
@@ -0,0 +1,82 @@
+package org.apache.maven.archiva.web.servlet.repository;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.RepositoryConfiguration;
+import org.codehaus.plexus.logging.Logger;
+
+import java.io.File;
+import java.io.IOException;
+
+import it.could.webdav.DAVListener;
+import it.could.webdav.DAVProcessor;
+import it.could.webdav.DAVRepository;
+import it.could.webdav.DAVResource;
+
+/**
+ * RepositoryMapping 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @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;
+    }
+
+    /**
+     * <p>Receive notification of an event occurred in a specific
+     * {@link DAVRepository}.</p>
+     */
+    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.debug(message + ": " + this.repositoryConfiguration.getId() + " : \"" + resource.getRelativePath() + "\"");
+    }
+}
index 42a46759e4a70e254ba0ccc059816e5d7c6b101b..bc41343373a959c3768204530f3e3f4b86ae9fa8 100644 (file)
@@ -1,24 +1,24 @@
 package org.apache.maven.archiva.web.util;
 
 /*
-* Copyright 2005 The Apache Software Foundation.
-*
-* Licensed 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.
-*/
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.ArchivaDefaults;
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
-import org.codehaus.plexus.security.rbac.Operation;
 import org.codehaus.plexus.security.rbac.Permission;
 import org.codehaus.plexus.security.rbac.RBACManager;
 import org.codehaus.plexus.security.rbac.RbacObjectNotFoundException;
@@ -43,191 +43,18 @@ public class DefaultRoleManager
      * @plexus.requirement
      */
     private RBACManager manager;
+    
+    /**
+     * @plexus.requirement
+     */
+    private ArchivaDefaults archivaDefaults;
 
     private boolean initialized;
                            
     public void initialize()
         throws InitializationException
     {
-
-        // initialize the operations
-
-        if ( !manager.operationExists( "add-repository" ) )
-        {
-            Operation operation = manager.createOperation( "add-repository" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "edit-repository" ) )
-        {
-            Operation operation = manager.createOperation( "edit-repository" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "delete-repository" ) )
-        {
-            Operation operation = manager.createOperation( "delete-repository" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "edit-configuration" ) )
-        {
-            Operation operation = manager.createOperation( "edit-configuration" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "run-indexer" ) )
-        {
-            Operation operation = manager.createOperation( "run-indexer" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "regenerate-index" ) )
-        {
-            Operation operation = manager.createOperation( "regenerate-index" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "access-reports" ) )
-        {
-            Operation operation = manager.createOperation( "access-reports" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "generate-reports" ) )
-        {
-            Operation operation = manager.createOperation( "generate-reports" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "edit-user" ) )
-        {
-            Operation operation = manager.createOperation( "edit-user" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "edit-all-users" ) )
-        {
-            Operation operation = manager.createOperation( "edit-all-users" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "grant-roles" ) )
-        {
-            Operation operation = manager.createOperation( "grant-roles" );
-            manager.saveOperation( operation );
-        }
-
-        if ( !manager.operationExists( "remove-roles" ) )
-        {
-            Operation operation = manager.createOperation( "remove-roles" );
-            manager.saveOperation( operation );
-        }
-
-        try
-        {
-            if ( !manager.permissionExists( "Edit Configuration" ) )
-            {
-                Permission editConfiguration = manager.createPermission( "Edit Configuration", "edit-configuration",
-                                                                         manager.getGlobalResource().getIdentifier() );
-                manager.savePermission( editConfiguration );
-            }
-
-            if ( !manager.permissionExists( "Run Indexer" ) )
-            {
-                Permission runIndexer = manager.createPermission( "Run Indexer", "run-indexer",
-                                                                  manager.getGlobalResource().getIdentifier() );
-
-                manager.savePermission( runIndexer );
-            }
-
-            if ( !manager.permissionExists( "Add Repository" ) )
-            {
-                Permission runIndexer = manager.createPermission( "Add Repository", "add-repository",
-                                                                  manager.getGlobalResource().getIdentifier() );
-                manager.savePermission( runIndexer );
-            }
-
-            if ( !manager.permissionExists( "Edit All Users" ) )
-            {
-                Permission editAllUsers = manager.createPermission( "Edit All Users", "edit-all-users",
-                                                                    manager.getGlobalResource().getIdentifier() );
-
-                manager.savePermission( editAllUsers );
-            }
-
-            if ( !manager.permissionExists( "Access Reports" ) )
-            {
-                Permission editAllUsers = manager.createPermission( "Access Reports", "access-reports",
-                                                                    manager.getGlobalResource().getIdentifier() );
-
-                manager.savePermission( editAllUsers );
-            }
-
-            if ( !manager.permissionExists( "Generate Reports" ) )
-            {
-                Permission editAllUsers = manager.createPermission( "Generate Reports", "generate-reports",
-                                                                    manager.getGlobalResource().getIdentifier() );
-
-                manager.savePermission( editAllUsers );
-            }           
-
-            if ( !manager.permissionExists( "Grant Roles" ) )
-            {
-                Permission granRoles = manager.createPermission( "Grant Roles", "grant-roles",
-                                                                    manager.getGlobalResource().getIdentifier() );
-
-                manager.savePermission( granRoles );
-            }
-            
-            if ( !manager.permissionExists( "Remove Roles" ) )
-            {
-                Permission removeRoles = manager.createPermission( "Remove Roles", "remove-roles",
-                                                                    manager.getGlobalResource().getIdentifier() );
-
-                manager.savePermission( removeRoles );
-            }
-
-            if ( !manager.permissionExists( "Regenerate Index" ) )
-            {
-                Permission regenIndex = manager.createPermission( "Regenerate Index", "regenerate-index",
-                                                                  manager.getGlobalResource().getIdentifier() );
-
-                manager.savePermission( regenIndex );
-            }
-
-            if ( !manager.roleExists( "User Administrator" ) )
-            {
-                Role userAdmin = manager.createRole( "User Administrator" );
-                userAdmin.addPermission( manager.getPermission( "Edit All Users" ) );
-                userAdmin.addPermission( manager.getPermission( "Remove Roles" ) );
-                userAdmin.addPermission( manager.getPermission( "Grant Roles" ) );
-                userAdmin.setAssignable( true );
-                manager.saveRole( userAdmin );
-            }
-
-            if ( !manager.roleExists( "System Administrator" ) )
-            {
-                Role admin = manager.createRole( "System Administrator" );
-                admin.addChildRoleName( manager.getRole( "User Administrator" ).getName() );
-                admin.addPermission( manager.getPermission( "Edit Configuration" ) );
-                admin.addPermission( manager.getPermission( "Run Indexer" ) );
-                admin.addPermission( manager.getPermission( "Add Repository" ) );
-                admin.addPermission( manager.getPermission( "Access Reports") );
-                admin.addPermission( manager.getPermission( "Generate Reports") );
-                admin.addPermission( manager.getPermission( "Regenerate Index" ) );
-                admin.setAssignable( true );
-                manager.saveRole( admin );
-            }
-
-
-        }
-        catch ( RbacObjectNotFoundException ne )
-        {
-            ne.printStackTrace();
-            throw new InitializationException( "error in role initialization", ne );
-        }
-
+        archivaDefaults.ensureDefaultsExist();
         initialized = true;
     }
 
@@ -250,7 +77,6 @@ public class DefaultRoleManager
         UserAssignment assignment = manager.createUserAssignment( principal );
         assignment.addRole( userRole );
         manager.saveUserAssignment( assignment );
-
     }
 
     /**
@@ -285,30 +111,41 @@ public class DefaultRoleManager
             repoResource = manager.saveResource( repoResource );
 
             // make the permissions
-            Permission editRepo = manager.createPermission( "Edit Repository - " + repositoryName );
-            editRepo.setOperation( manager.getOperation( "edit-repository" ) );
+            Permission editRepo = manager.createPermission( ArchivaDefaults.REPOSITORY_EDIT + " - " + repositoryName );
+            editRepo.setOperation( manager.getOperation( ArchivaDefaults.REPOSITORY_EDIT_OPERATION ) );
             editRepo.setResource( repoResource );
             editRepo = manager.savePermission( editRepo );
 
-            Permission deleteRepo = manager.createPermission( "Delete Repository - " + repositoryName );
-            deleteRepo.setOperation( manager.getOperation( "delete-repository" ) );
+            Permission deleteRepo = manager.createPermission( ArchivaDefaults.REPOSITORY_DELETE + " - " + repositoryName );
+            deleteRepo.setOperation( manager.getOperation( ArchivaDefaults.REPOSITORY_DELETE_OPERATION ) );
             deleteRepo.setResource( repoResource );
             deleteRepo = manager.savePermission( deleteRepo );
+            
+            Permission accessRepo = manager.createPermission( ArchivaDefaults.REPOSITORY_ACCESS + " - " + repositoryName );
+            accessRepo.setOperation( manager.getOperation( ArchivaDefaults.REPOSITORY_ACCESS_OPERATION ) );
+            accessRepo.setResource( repoResource );
+            accessRepo = manager.savePermission( accessRepo );
+            
+            Permission uploadRepo = manager.createPermission( ArchivaDefaults.REPOSITORY_UPLOAD + " - " + repositoryName );
+            uploadRepo.setOperation( manager.getOperation( ArchivaDefaults.REPOSITORY_UPLOAD_OPERATION ) );
+            uploadRepo.setResource( repoResource );
+            uploadRepo = manager.savePermission( uploadRepo );
 
             // make the roles
             Role repositoryObserver = manager.createRole( "Repository Observer - " + repositoryName );
-            repositoryObserver.addPermission( manager.getPermission( "Access Reports" ) );
+            repositoryObserver.addPermission( manager.getPermission( ArchivaDefaults.REPORTS_ACCESS_PERMISSION ) );
             repositoryObserver.setAssignable( true );
             repositoryObserver = manager.saveRole( repositoryObserver );
 
             Role repositoryManager = manager.createRole( "Repository Manager - " + repositoryName );
             repositoryManager.addPermission( editRepo );
             repositoryManager.addPermission( deleteRepo );
-            repositoryManager.addPermission( manager.getPermission( "Generate Reports" ) );
+            repositoryManager.addPermission( accessRepo );
+            repositoryManager.addPermission( uploadRepo );
+            repositoryManager.addPermission( manager.getPermission( ArchivaDefaults.REPORTS_GENERATE_PERMISSION ) );
             repositoryManager.addChildRoleName( repositoryObserver.getName() );
             repositoryManager.setAssignable( true );
             manager.saveRole( repositoryManager );
-
         }
         catch ( RbacObjectNotFoundException ne )
         {
index 6242bf7be573075ea81b8b05f5549c3cece7b27e..88c26e056ce44e898501dfb69114dbcc583f505d 100644 (file)
   <listener>
     <listener-class>org.codehaus.plexus.xwork.PlexusLifecycleListener</listener-class>
   </listener>
+  
+  <servlet>
+    <servlet-name>RepositoryAccessServlet</servlet-name>
+    <servlet-class>org.apache.maven.archiva.web.servlet.PlexusComponentServlet</servlet-class>
+    <init-param>
+      <param-name>key</param-name>
+      <param-value>repositoryAccess</param-value>
+    </init-param>
+  </servlet>
+  
+  <servlet-mapping>
+    <servlet-name>RepositoryAccessServlet</servlet-name>
+    <url-pattern>/repository/*</url-pattern>
+  </servlet-mapping>
+  
 </web-app>