You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by oc...@apache.org on 2008/05/22 12:02:29 UTC

svn commit: r659069 - in /archiva/trunk/archiva-modules/archiva-web: archiva-security/src/main/java/org/apache/maven/archiva/security/ archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/ archiva-webapp/src/test/java/org/apache/maven/a...

Author: oching
Date: Thu May 22 03:02:29 2008
New Revision: 659069

URL: http://svn.apache.org/viewvc?rev=659069&view=rev
Log:
[MRM-694]
-fix virtual repo authentication problem

Modified:
    archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java
    archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/RepositoryServletRepositoryGroupTest.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/rss/SecuritySystemStub.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java?rev=659069&r1=659068&r2=659069&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java Thu May 22 03:02:29 2008
@@ -29,8 +29,11 @@
 import org.codehaus.plexus.redback.authorization.UnauthorizedException;
 import org.codehaus.plexus.redback.policy.AccountLockedException;
 import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.codehaus.plexus.redback.system.DefaultSecuritySession;
 import org.codehaus.plexus.redback.system.SecuritySession;
 import org.codehaus.plexus.redback.system.SecuritySystem;
+import org.codehaus.plexus.redback.users.User;
+import org.codehaus.plexus.redback.users.UserNotFoundException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -63,8 +66,8 @@
                                  boolean isWriteRequest )
         throws AuthorizationException, UnauthorizedException
     {
-        // also check for permission to proxy the resource when MRM-579 is implemented
-        
+        // TODO: also check for permission to proxy the resource when MRM-579 is implemented
+
         String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
 
         if ( isWriteRequest )
@@ -89,4 +92,31 @@
 
         return true;
     }
+
+    public boolean isAuthorizedToAccessVirtualRepository( String principal, String repoId )
+        throws UnauthorizedException
+    {
+        try
+        {
+            User user = securitySystem.getUserManager().findUser( principal );
+            if ( user.isLocked() )
+            {
+                throw new UnauthorizedException( "User account is locked." );
+            }
+
+            AuthenticationResult authn = new AuthenticationResult( true, principal, null );
+            SecuritySession securitySession = new DefaultSecuritySession( authn, user );
+
+            return securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
+                                                repoId );
+        }
+        catch ( UserNotFoundException e )
+        {
+            throw new UnauthorizedException( e.getMessage() );
+        }
+        catch ( AuthorizationException e )
+        {
+            throw new UnauthorizedException( e.getMessage() );
+        }
+    }
 }

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java?rev=659069&r1=659068&r2=659069&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java Thu May 22 03:02:29 2008
@@ -40,4 +40,7 @@
 
     public boolean isAuthorized( HttpServletRequest request, SecuritySession securitySession, String repositoryId,
         boolean isWriteRequest ) throws AuthorizationException, UnauthorizedException;
+    
+    public boolean isAuthorizedToAccessVirtualRepository( String principal, String repoId )
+        throws UnauthorizedException;
 }

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/RepositoryServletRepositoryGroupTest.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/RepositoryServletRepositoryGroupTest.java?rev=659069&r1=659068&r2=659069&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/RepositoryServletRepositoryGroupTest.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/RepositoryServletRepositoryGroupTest.java Thu May 22 03:02:29 2008
@@ -215,7 +215,7 @@
         WebResponse response = sc.getResponse( request );
                 
         assertNotNull( "Should have received a response", response );
-        assertResponseOK( response );
+        assertEquals( "Should have been an 401 response code.", HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );
     }
         
     protected void assertResponseBadRequest( WebResponse response )

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/rss/SecuritySystemStub.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/rss/SecuritySystemStub.java?rev=659069&r1=659068&r2=659069&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/rss/SecuritySystemStub.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/rss/SecuritySystemStub.java Thu May 22 03:02:29 2008
@@ -24,7 +24,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
 import org.codehaus.plexus.redback.authentication.AuthenticationDataSource;
 import org.codehaus.plexus.redback.authentication.AuthenticationException;
 import org.codehaus.plexus.redback.authentication.AuthenticationResult;

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java?rev=659069&r1=659068&r2=659069&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java Thu May 22 03:02:29 2008
@@ -56,6 +56,7 @@
 import org.codehaus.plexus.redback.policy.AccountLockedException;
 import org.codehaus.plexus.redback.policy.MustChangePasswordException;
 import org.codehaus.plexus.redback.system.SecuritySession;
+import org.codehaus.plexus.redback.system.SecuritySystemConstants;
 import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 import org.slf4j.Logger;
@@ -63,7 +64,9 @@
 
 import javax.servlet.http.HttpServletResponse;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.io.*;
 
 /**
@@ -123,7 +126,7 @@
     public DavResource createResource( final DavResourceLocator locator, final DavServletRequest request,
                                        final DavServletResponse response )
         throws DavException
-    {        
+    {   
         checkLocatorIsInstanceOfRepositoryLocator( locator );
         ArchivaDavResourceLocator archivaLocator = (ArchivaDavResourceLocator) locator;
         
@@ -636,7 +639,7 @@
         {
             AuthenticationResult result = httpAuth.getAuthenticationResult( request, null );            
             SecuritySession securitySession = httpAuth.getSecuritySession();
-            
+                       
             return servletAuth.isAuthenticated( request, result ) &&
                 servletAuth.isAuthorized( request, securitySession, repositoryId,
                                           WebdavMethodUtil.isWriteMethod( request.getMethod() ) );
@@ -671,36 +674,63 @@
         LogicalResource logicalResource =
             new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) );
         
-        for( String repository : repositories )
+        // flow: 
+        // if the current user logged in has permission to any of the repositories, allow user to
+        // browse the repo group but displaying only the repositories which the user has permission to access.
+        // otherwise, prompt for authentication.
+        
+        // put the current session in the session map which will be passed to ArchivaXworkUser
+        Map<String, Object> sessionMap = new HashMap<String, Object>();
+        if( request.getSession().getAttribute( SecuritySystemConstants.SECURITY_SESSION_KEY ) != null )
         {
-            ManagedRepositoryContent managedRepository = null;
-
-            try
-            {
-                managedRepository = getManagedRepository( repository );
-            }
-            catch ( DavException de )
-            {
-                throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Invalid managed repository <" +
-                    repository + ">" );
-            }
-            
-            if( isAuthorized( request, repository ) )
-            {
-                if ( !locator.getResourcePath().startsWith( ArchivaVirtualDavResource.HIDDEN_PATH_PREFIX ) )
+            sessionMap.put( SecuritySystemConstants.SECURITY_SESSION_KEY, 
+                            request.getSession().getAttribute( SecuritySystemConstants.SECURITY_SESSION_KEY ) );
+        }
+        
+        String activePrincipal = ArchivaXworkUser.getActivePrincipal( sessionMap );        
+        boolean allow = isAllowedToContinue( request, repositories, activePrincipal );
+              
+        if( allow )
+        {            
+            for( String repository : repositories )
+            {    
+                // for prompted authentication
+                if( httpAuth.getSecuritySession() != null )
                 {
-                    if( managedRepository != null )
+                    try
                     {   
-                        File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
-                        if( resourceFile.exists() )
+                        if( isAuthorized( request, repository ) )                        
                         {
-                            mergedRepositoryContents.add( resourceFile );
-                        }                    
+                            getResource( locator, mergedRepositoryContents, logicalResource, repository );
+                        }
+                    }                    
+                    catch ( DavException e )
+                    {                        
+                        continue;
                     }
                 }
+                else
+                {
+                    // for the current user logged in 
+                    try
+                    {
+                        if( servletAuth.isAuthorizedToAccessVirtualRepository( activePrincipal, repository ) )
+                        {
+                            getResource( locator, mergedRepositoryContents, logicalResource, repository );
+                        }
+                    }
+                    catch ( UnauthorizedException e )                    
+                    {                        
+                        continue;
+                    }
+                }                
             }
-        }      
-                
+        }
+        else
+        {
+            throw new UnauthorizedDavException( locator.getRepositoryId(), "User not authorized." );
+        }
+        
         ArchivaVirtualDavResource resource =
             new ArchivaVirtualDavResource( mergedRepositoryContents, logicalResource.getPath(), mimeTypes, locator, this );
        
@@ -712,5 +742,88 @@
         
         return resource;
     }
+
+    private void getResource( ArchivaDavResourceLocator locator, List<File> mergedRepositoryContents,
+                              LogicalResource logicalResource, String repository )
+        throws DavException
+    {
+        ManagedRepositoryContent managedRepository = null;
+
+        try
+        {
+            managedRepository = getManagedRepository( repository );
+        }
+        catch ( DavException de )
+        {
+            throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Invalid managed repository <" +
+                repository + ">" );
+        }                            
+        
+        if ( !locator.getResourcePath().startsWith( ArchivaVirtualDavResource.HIDDEN_PATH_PREFIX ) )
+        {
+            if( managedRepository != null )
+            {   
+                File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
+                if( resourceFile.exists() )
+                {                    
+                    mergedRepositoryContents.add( resourceFile );
+                }                    
+            }
+        }
+    }
     
+    /**
+     * Check if the current user is authorized to access any of the repos
+     *  
+     * @param request
+     * @param repositories
+     * @param activePrincipal
+     * @return
+     */
+    private boolean isAllowedToContinue( DavServletRequest request, List<String> repositories, String activePrincipal )    
+    {
+        boolean allow = false;
+        
+              
+        // if securitySession != null, it means that the user was prompted for authentication
+        if( httpAuth.getSecuritySession() != null )
+        {
+            for( String repository : repositories )
+            {
+                try
+                {
+                    if( isAuthorized( request, repository ) )
+                    {
+                        allow = true;
+                        break;
+                    }
+                }
+                catch( DavException e )
+                {                    
+                    continue;
+                }
+            }  
+        }
+        else
+        {   
+            for( String repository : repositories )
+            {
+                try
+                {
+                    if( servletAuth.isAuthorizedToAccessVirtualRepository( activePrincipal, repository ) )
+                    {
+                        allow = true;
+                        break;
+                    }
+                }
+                catch ( UnauthorizedException e )
+                {                    
+                    continue;
+                }
+            }  
+        }
+        
+        return allow;
+    }
+        
 }